c++ - 如何将值添加到列表>
问题描述
我需要将派生类的元素添加到抽象类的共享指针列表中。
我一直在尝试这个。我知道我正在尝试在下面的示例中创建抽象类的实例,但我不知道如何使其工作。
简化的类如下所示:
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
不是抽象的,它将编译并看起来可以工作。但这会导致创建切片共享对象。
如何解决?
您需要本着原型设计模式的精神使用虚拟克隆功能:
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);
}
补充说明
如果您精通方法链接,我想您会想要AddData()
返回一个引用。如果不是,那么每次调用AddData()
时,都会创建 的副本Data
,这会创建大量不必要的副本。
推荐阅读
- jax-rs - 将@Named bean 注入 Jax-Rs 类
- sqlite - 如何在 SQLite 中使用 LIMIT 选择 TOP 1 结果_without_?
- javascript - 异步方法总是返回 undefined
- c# - Unity 麦克风无法正常工作,停止游戏时出错
- r - 如何通过循环将集合添加到数据框?
- maven - 为什么maven会忽略测试依赖项中定义的编译传递依赖项的版本
- python - 替换熊猫中的多个列值
- sql - 如何在 SQL Server 表行中拆分数据
- unity3d - 如何在 Vuforia Unity 中获取 ImageTarget 的 4 个角的 3D 空间坐标?
- apache-poi - SlideShowExtractor NoSuchMethodError org.apache.poi.sl.usermodel.Sheet.getPlaceholderDetails