工厂方法创建shared_ptr对象

时间:2014-08-01 16:39:43

标签: c++ visual-c++ polymorphism shared-ptr

当使用工厂创建对象时,例如在下面的示例中,在某些情况下,shared_ptr包裹的对象显然会在返回过程中被删除(在调试期间,对象创建正常但是当它被创建时分配给this->xs抛出异常)。当我更改工厂方法以返回原始指针,并且Link::xs成员为unique_ptr时,代码运行正常。 shared_ptr引发了什么导致它以这种方式行事?它与shared_ptr<CrossSection>包装Circular对象的事实有关吗?使用MS Visual C ++ 2012进行了测试。

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());
        }
    }
}

2 个答案:

答案 0 :(得分:6)

因此,Martin有一个解决析构函数问题的方法。您可以添加虚拟析构函数。

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

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());
}

或者,甚至更好:

std::shared_ptr<CrossSection> Factory::create(const std::string& type)
{
    if (geom == "circular")
        return std::make_shared<Circular>();
    else
        return std::make_shared<Dummy>();
}

答案 1 :(得分:3)

你肯定需要在你的CrossSection基类中定义一个虚拟析构函数,以便使用多态,即为了声明派生类并使用它们代替父类(所以通常几乎每次你想要使用派生类...)

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

参见例如When to use virtual destructors?Should every class have a virtual destructor?了解更多解释。

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