关于c ++:创建shared_ptr对象的Factory方法

Factory method creating shared_ptr object

当使用工厂创建一个对象时,例如在下面的示例中,在某些情况下,由shared_ptr包装的对象在返回过程中显然会被删除(在调试过程中,对象创建正常,但当它被分配给this->xs时,会引发异常)。当我将factory方法更改为返回原始指针,并且Link::xs成员为unique_ptr时,代码运行良好。在引擎盖下面发生了什么事情,使它以这种方式运行?是否与shared_ptr包住Circular物体有关?使用MS Visual C++ 2012进行了测试。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
class Link
{
private:
    std::shared_ptr<xs::CrossSection> xs;
public:
    void parseXsection(const std::vector<std::string>& parts);
    std::shared_ptr<xs::CrossSection> getXs() { return this->xs; }
};
void Link::parseXsection(const std::vector<std::string>& parts)
{
    this->xs = xs::Factory::create(parts[1]);
}

namespace xs
{
    class CrossSection
    {
    };
    class Circular : public CrossSection
    {
    };
    class Dummy : public CrossSection
    {
    };
    class Factory
    {
    public:
        static std::shared_ptr<CrossSection> create(const std::string& type);
    };
    std::shared_ptr<CrossSection> Factory::create(const std::string& type)
    {
        if (geom =="circular")
        {
            return std::shared_ptr<CrossSection>(new Circular());
        }
        else
        {
            return std::shared_ptr<CrossSection>(new Dummy());
        }
    }
}


所以,马丁有一个解决析构函数问题的选项。可以添加虚拟析构函数。

但是,因为您使用的是std::shared_ptr,它使用了一些类型的擦除,所以您可以做一个较小的修复:

1
2
3
4
5
6
7
std::shared_ptr<CrossSection> Factory::create(const std::string& type)
{
    if (geom =="circular")
        return std::shared_ptr<Circular>(new Circular());
    else
        return std::shared_ptr<Dummy>(new Dummy());
}

或者,更好的是:

1
2
3
4
5
6
7
std::shared_ptr<CrossSection> Factory::create(const std::string& type)
{
    if (geom =="circular")
        return std::make_shared<Circular>();
    else
        return std::make_shared<Dummy>();
}


为了使用多态性,您肯定需要在CrossSection基类中定义一个虚拟析构函数,也就是说,为了声明派生类并使用它们来代替父类(因此,通常情况下,您几乎每次都要使用派生类…)

1
2
3
4
class CrossSection {
  public:
    virtual ~CrossSection() { /* Nothing to do here ... */ }
};

例如,什么时候使用虚拟析构函数?或者每个类都应该有一个虚拟析构函数?更多解释。

附言:我现在不能说,如果这是你和shared_ptr的问题的原因,但它看起来很像你可能会遇到的问题,如果你忘记了虚拟析构函数…