如何将值添加到list< shared_ptr< Abstract>> [英] How to add values to list<shared_ptr<Abstract>>
问题描述
我需要将派生类的元素添加到抽象类的共享指针列表中.
I need to add elements of derived classes into list of shared pointers to abstract class.
我一直在尝试.我知道我在下面的示例中尝试创建抽象类的实例,但是我不知道如何使它起作用.
I've been trying this. I know that I am trying to create instance of abstract class in the example below, but I have no idea how to make it work.
简化的类如下:
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.我愿意接受不同的解决方案.我只需要以某种方式将不同类型的元素存储到单个容器中即可.
I want to avoid RTII and dynamic_cast. I am open to different solutions. I just need to somehow store elements of different types into single container.
我需要像这样使用类数据:
I need to use class Data like this:
Data test("Random Name");
test.AddData(A(1,2))
.AddData(B(3))
.AddData(B(4));
推荐答案
出了什么问题?
问题是make_shared<X>
将通过调用X
的构造函数来创建共享对象.在您的情况下,这是不可能的,因为它是抽象类型.因此,它甚至不会编译.
What's the problem ?
The problem is that make_shared<X>
will create a shared object by invoking the constructor of X
. In your case this is not possible, since it's an abstract type. So it won't even compile.
如果X
不是抽象的,它将编译并似乎可以工作.但这会导致创建切片共享对象.
If X
would not be abstract, it would compile and appear to work. But it would result in creating a sliced shared object.
您需要本着原型设计模式:
class Abstract
{
public:
virtual string toString() const = 0;
virtual shared_ptr<Abstract> clone() const= 0;
};
您必须在派生类中覆盖它,例如:
You'll have to override it in the derived classes, for example:
class B : public Abstract
{
public:
...
shared_ptr<Abstract> clone() const override { return make_shared<B>(*this); }
...
};
然后您可以利用多态性填充列表:
You may then populate the list taking advantage of the polymorphism:
Data& AddData ( const Abstract & a ) // return preferably a reference
{
//Need to fix next line
l1.push_back(a.clone());
return (*this);
}
如果您是方法链接的专家,我认为您想要AddData()
返回引用.如果不是,那么每次调用AddData()
时,都将创建一个Data
的副本,这将创建很多不必要的副本.
If you're an adept of method chaining, I think you'd want AddData()
to return a reference. If not, then each time you'd invoke AddData()
, you would create a copy of Data
, which would create an awful lot of unnecessary copies.
这篇关于如何将值添加到list< shared_ptr< Abstract>>的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!