C++ 抽象类中的复制控制

C++ 抽象类中的复制控制,c++,shared-ptr,copy-constructor,C++,Shared Ptr,Copy Constructor,我有一个抽象类和两个具体子类(Store),它们都有一个指向另一个具体子类的指针,该子类是从抽象类(Factory)派生的。下面是商店的代码。我想防止内存泄漏,所以我开始编写复制控件。然而,我不能实例化一个新工厂,因为我不知道它将是什么类型。规避这一问题的好做法是什么?我可以在具体的存储中编写复制控件,但是我有重复的代码。 我也尝试使用智能指针,但在那里我发现了另一个困难。代码片段myFactory=std::make_shared(ConcreteFactoryA())首先创建一个Abstra

我有一个抽象类和两个具体子类(Store),它们都有一个指向另一个具体子类的指针,该子类是从抽象类(Factory)派生的。下面是商店的代码。我想防止内存泄漏,所以我开始编写复制控件。然而,我不能实例化一个新工厂,因为我不知道它将是什么类型。规避这一问题的好做法是什么?我可以在具体的存储中编写复制控件,但是我有重复的代码。 我也尝试使用智能指针,但在那里我发现了另一个困难。代码片段
myFactory=std::make_shared(ConcreteFactoryA())首先创建一个AbstractFactory,然后用一个ConcreteFactoryA填充它。然而,顾名思义,正如编译器告诉我的,AbstractFactory不能被实例化。您可以将共享的PTR与抽象类一起使用吗

使用普通指针的代码:

#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) {}
};
使用智能指针的代码:

#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) {}
};
#pragma一次
#包括“AbstractFactory.h”
#包括
类抽象存储
{
公众:
//复制控制
AbstractStore(const AbstractStore&orig):myFactory(orig.myFactory){}
AbstractStore&operator=(const AbstractStore&orig){myFactory=orig.myFactory;返回*this;}
~AbstractStore(void){}
受保护的:
//建造师
AbstractStore(void){}
//数据成员
std::共享工厂;
};
类ConcreteStoreA:公共抽象存储
{
公众:
ConcreteStoreA(void){myFactory=std::make_shared(ConcreteFactoryA());}
~a(空){}
};
类ConcreteStoreB:公共抽象存储
{
公众:
ConcreteStoreB(void){myFactory=std::make_shared(ConcreteFactoryB());}
~b(无效){}
};

您没有正确使用
共享
。使用:

std::make_shared<ConcreteFactory>();
std::使_共享();
你在这里没有任何论据地称它
make_shared
不接受构造的对象,而是接受转发给其构造函数的参数。在您的情况下,您将转发到copy构造函数,它在抽象层次结构中工作得很差。如果要在层次结构中复制对象,请使用具有协变返回类型的
clone
成员函数


这将返回一个
shared\u ptr
,它将被转换为
shared\u ptr。此外,还可以使用构造函数初始值设定项列表和虚拟析构函数。

您可能需要以下两种方法之一才能使智能指针方法正常工作:

  • 使
    ConcreteFactoryA
    ConcreteFactoryB
    返回一个
    std::shared\u ptr
    std::unique\u ptr
    。在“存储”类中简单地分配,或者更好地初始化

  • 使用
    std::shared_ptr::reset
    或构造函数从原始指针初始化
    shared_ptr
    s


  • 您通常只使用智能指针的
    std::make_shared
    ,而使用原始指针的
    new
    。在您的例子中,您只是简单地分配了指针,所以不应该使用它。

    旁注:抽象类中的所有析构函数可能都需要声明为
    virtual
    I将具体存储的构造函数更改为
    ConcreteStoreA(void):AbstractStore(std::make_shared(ConcreteFactoryA()){}
    ,现在它可以工作了。这就是你的意思吗?因为我这里还有一个论点列表。编辑:我不理解你的论点列表中的句子,但现在我理解了。我删除了这个论点。不过我还是不明白你第一段的最后一句话。什么是协变返回类型?@physicalattraction在派生类中重写的虚拟函数可以将返回类型更改为更窄的类型。看见