在抽象类中复制控件

时间:2012-07-16 09:21:12

标签: c++ shared-ptr copy-constructor

我有一个抽象类和两个具体的子类(Store),两者都有一个指向另一个具体子类的指针,该子类派生自一个抽象类(Factory)。以下是商店的代码。我想防止内存泄漏,所以我开始编写复制控件。我不能实例化一个新的工厂,因为我不知道它将是什么类型。绕过这个是什么好习惯?我可以在具体的商店中编写复制控件,但后来我有重复的代码。 我也尝试使用智能指针,但在那里我发现了另一个困难。代码段myFactory = std::make_shared<AbstractFactory>(ConcreteFactoryA());首先显然创建了一个AbstractFactory,然后用ConcreteFactoryA填充它。但是,顾名思义,AbstractFactory无法实例化,正如编译器告诉我的那样。你可以将shared_ptrs与抽象类一起使用吗?

带有普通指针的代码:

#pragma once
#include "AbstractFactory.h"

class AbstractStore
{
public:
    // Copy control
    AbstractStore(const AbstractStore& orig) : myFactory(new AbstractFactory(orig.myFactory)) {}
    AbstractStore& operator=(const AbstractStore& orig) { return *this; } // TODO
    ~AbstractStore(void) {}
protected:
    // Constructor
    AbstractStore(void) {}
    // Data members
    AbstractFactory* myFactory;
};

class ConcreteStoreA : public AbstractStore
{
public:
    ConcreteStoreA(void) { myFactory = new ConcreteFactoryA; }
    ~ConcreteStoreA(void) {}
};

class ConcreteStoreB : public AbstractStore
{
public:
    ConcreteStoreB(void) { myFactory = new ConcreteFactoryB; }
    ~ConcreteStoreB(void) {}
};

智能指针代码:

#pragma once
#include "AbstractFactory.h"
#include <memory>

class AbstractStore
{
public:
    // Copy control
    AbstractStore(const AbstractStore& orig) : myFactory(orig.myFactory) {}
    AbstractStore& operator=(const AbstractStore& orig) { myFactory = orig.myFactory; return *this; }
    ~AbstractStore(void) {}
protected:
    // Constructor
    AbstractStore(void) {}
    // Data members
    std::shared_ptr<AbstractFactory> myFactory;
};

class ConcreteStoreA : public AbstractStore
{
public:
    ConcreteStoreA(void) { myFactory = std::make_shared<AbstractFactory>(ConcreteFactoryA()); }
    ~ConcreteStoreA(void) {}
};

class ConcreteStoreB : public AbstractStore
{
public:
    ConcreteStoreB(void) { myFactory = std::make_shared<AbstractFactory>(ConcreteFactoryB()); }
    ~ConcreteStoreB(void) {}
};

2 个答案:

答案 0 :(得分:2)

您没有正确使用make_shared。使用:

std::make_shared<ConcreteFactory>();

你在这里没有任何参数调用它。 make_shared不接受构造对象,而是接受转发给它的构造函数的参数。在您的情况下,您将转发到复制构造函数,该构造函数与抽象层次结构很差。如果要在层次结构中使用可复制对象,请使用带有协变返回类型的clone成员函数。

这将返回一个shared_ptr<ConcreteFactory>,它将在作业中转换为shared_ptr<AbstractFactory>(参见(9)here。另外,使用构造函数初始化列表和虚拟析构函数。

答案 1 :(得分:0)

你可能想要这两件事中的一件让你的智能指针接近工作:

  1. ConcreteFactoryAConcreteFactoryB返回std::shared_ptr<AbstractFactory>std::unique_ptr<AbstractFactory>。只需在“商店”类中分配或更好地初始化

  2. 使用shared_ptr<>或构造函数

  3. 从原始指针初始化std::shared_ptr<>::reset

    您通常只使用std::make_shared<>智能指针,其中new使用原始指针。在您的情况下,您只需指定指针,因此不应使用它。