c++ - 如何向列表添加值<shared_ptr<Abstract>>

标签 c++ list polymorphism abstract-class shared-ptr

我需要将派生类的元素添加到抽象类的共享指针列表中。

我一直在尝试这个。我知道我正在尝试在下面的示例中创建抽象类的实例,但我不知道如何使其工作。

简化的类如下所示:


using namespace std;

class Abstract
{
  public:
    virtual string toString() const = 0;
};


class A : public Abstract
{
  public:
    A(int a, int b) : a(a), b(b)
    {}
    string toString() const { return "A"; }
  private:
    int a;
    int b;

};
class B : public Abstract
{
  public:
    B(int b) : b(b)
    {}
    string toString() const { return "B"; }
  private:
    int b;
};

问题出在以下类中:

class Data
{
  public:
    Data(const string & name) : name (name) 
    {}
    Data AddData ( const Abstract & a )
    {
        //Need to fix next line
        l1.push_back(make_shared<Abstract>(a));
        return (*this);   
    }
  private:
    list<shared_ptr<Abstract>> l1;
    string name;
};

我想避免RTII和dynamic_cast。我对不同的解决方案持开放态度。我只需要以某种方式将不同类型的元素存储到单个容器中。

我需要像这样使用类数据:

    Data test("Random Name");

    test.AddData(A(1,2)) 
        .AddData(B(3))
        .AddData(B(4));

最佳答案

有什么问题吗?

问题是 make_shared<X>将通过调用 X 的构造函数来创建共享对象。在你的情况下这是不可能的,因为它是一个抽象类型。所以它甚至无法编译。

如果X不会是抽象的,它会编译并且看起来可以工作。但这会导致创建一个 sliced共享对象。

如何解决?

您需要本着 prototype design pattern 的精神使用虚拟克隆功能:

class Abstract
{
  public:
    virtual string toString() const = 0;
    virtual shared_ptr<Abstract> clone() const= 0; 
};

您必须在派生类中重写它,例如:

class B : public Abstract
{
  public:
    ...
    shared_ptr<Abstract> clone() const override { return make_shared<B>(*this); } 
  ...
};

然后您可以利用多态性来填充列表:

Data& AddData ( const Abstract & a )   // return preferably a reference
{
    //Need to fix next line
    l1.push_back(a.clone());
    return (*this);   
}

Online demo

补充说明

如果您擅长method chaining ,我想你会想要 AddData()返回一个引用。如果没有,那么每次您都会调用 AddData() ,您将创建 Data 的拷贝,这会创建大量不必要的拷贝。

关于c++ - 如何向列表添加值<shared_ptr<Abstract>>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55879042/

相关文章:

c++ - 当可以返回错误/异常时,从库中终止调用程序(例如,调用 exit())总是错误的吗?

c++ - 如何在 C++ 中显示长度超过 1 个小数点的答案

list - 基于逻辑条件的列表中的子集元素

c++ - 用于分配成员函数指针的 lambda 表达式

c++ - 配置 Visual Studio 以创建 32 位和 64 位配置

c++ - 在程序中使用函数会加快执行速度吗?

c++ - 如何在没有 'new' 的情况下将新对象实例添加到 std::list

python - 从列表列表中随机选择 X 个列表

java - 当您可以只使用具体类型时,为什么会有带有上限的通配符?

java - 继承两个Java类