gpt4 book ai didi

c++ - 如何将值添加到列表>

转载 作者:搜寻专家 更新时间:2023-10-31 02:03:11 28 4
gpt4 key购买 nike

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

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

简化的类如下所示:


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/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com