我有一个抽象类和两个具体的子类(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) {}
};
答案 0 :(得分:2)
您没有正确使用make_shared
。使用:
std::make_shared<ConcreteFactory>();
你在这里没有任何参数调用它。 make_shared
不接受构造对象,而是接受转发给它的构造函数的参数。在您的情况下,您将转发到复制构造函数,该构造函数与抽象层次结构很差。如果要在层次结构中使用可复制对象,请使用带有协变返回类型的clone
成员函数。
这将返回一个shared_ptr<ConcreteFactory>
,它将在作业中转换为shared_ptr<AbstractFactory>
(参见(9)here。另外,使用构造函数初始化列表和虚拟析构函数。
答案 1 :(得分:0)
你可能想要这两件事中的一件让你的智能指针接近工作:
让ConcreteFactoryA
和ConcreteFactoryB
返回std::shared_ptr<AbstractFactory>
或std::unique_ptr<AbstractFactory>
。只需在“商店”类中分配或更好地初始化
使用shared_ptr<>
或构造函数
std::shared_ptr<>::reset
醇>
您通常只使用std::make_shared<>
智能指针,其中new
使用原始指针。在您的情况下,您只需指定指针,因此不应使用它。