C++ 如何向列表中添加值<;共享\u ptr<;摘要>&燃气轮机;
我需要将派生类的元素添加到抽象类的共享指针列表中 我一直在试这个。我知道我正试图在下面的示例中创建抽象类的实例,但我不知道如何使其工作 简化类如下所示:C++ 如何向列表中添加值<;共享\u ptr<;摘要>&燃气轮机;,c++,list,polymorphism,abstract-class,shared-ptr,C++,List,Polymorphism,Abstract Class,Shared Ptr,我需要将派生类的元素添加到抽象类的共享指针列表中 我一直在试这个。我知道我正试图在下面的示例中创建抽象类的实例,但我不知道如何使其工作 简化类如下所示: 使用名称空间std; 类摘要 { 公众: 虚拟字符串toString()常量=0; }; A类:公开摘要 { 公众: A(inta,intb):A(A),b(b) {} 字符串toString()常量{返回“A”;} 私人: INTA; int b; }; B类:公开摘要 { 公众: B(国际B):B(B) {} 字符串toString()常
使用名称空间std;
类摘要
{
公众:
虚拟字符串toString()常量=0;
};
A类:公开摘要
{
公众:
A(inta,intb):A(A),b(b)
{}
字符串toString()常量{返回“A”;}
私人:
INTA;
int b;
};
B类:公开摘要
{
公众:
B(国际B):B(B)
{}
字符串toString()常量{返回“B”;}
私人:
int b;
};
问题在以下类别中:
类数据
{
公众:
数据(常量字符串和名称):名称(名称)
{}
数据添加数据(常量摘要和a)
{
//需要修下一行吗
l1.推回(使共享(a));
返回(*本条);
}
私人:
列表l1;
字符串名;
};
我想避免RTII和动态_cast。我对不同的解决方案持开放态度。我只需要以某种方式将不同类型的元素存储到单个容器中
我需要像这样使用类数据:
数据测试(“随机名称”);
试验数据(A(1,2))
.AddData(B(3))
.AddData(B(4));
有什么问题吗?
问题是make_shared
将通过调用X
的构造函数来创建共享对象。在您的情况下,这是不可能的,因为它是一个抽象类型。所以它甚至不会编译
如果X
不是抽象的,那么它将编译并看起来正常工作。但这将导致创建一个共享对象
如何解决?
您需要本着以下精神使用虚拟克隆功能:
补充说明
如果你是一个熟练的程序员,我想你应该希望
AddData()
返回一个引用。如果没有,那么每次调用AddData()
,都会创建数据的副本,这将创建大量不必要的副本。您无法将抽象类实例推送到列表中。我要么重载AddData()函数,要么使用模板
class Data
{
public:
Data(const string & name) : name (name) {}
Data& AddData (const A &a)
{
l1.push_back(make_shared<A>(a));
return (*this);
}
Data& AddData (const B &b)
{
l1.push_back(make_shared<B>(b));
return (*this);
}
private:
list<shared_ptr<Abstract>> l1;
string name;
};
类数据
{
公众:
数据(常量字符串和名称):名称(名称){}
数据和添加数据(常数A和A)
{
l1.推回(使共享(a));
返回(*本条);
}
数据和添加数据(常数B和B)
{
l1.推回(使共享(b));
返回(*本条);
}
私人:
列表l1;
字符串名;
};
或
类数据
{
公众:
数据(常量字符串和名称):名称(名称){}
模板
数据和添加数据(常数T&a)
{
l1.推回(使共享(a));
返回(*本条);
}
私人:
列表l1;
字符串名;
};
不能创建抽象类的实例。如果要实例化A
或B
对象,您需要在Data
中以某种方式做出决定。谢谢。这正是我需要的。虽然这两种方法都可以考虑,但它们都依赖于编译时已知的对象类型。因此,它适用于OP的示例,其中添加的对象的类型在编译时是已知的。然而,在多态用例中,它会失败,例如,如果您试图添加一个像这样定义的引用c:bb(5);摘要&c=b代码>()
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);
}
class Data
{
public:
Data(const string & name) : name (name) {}
Data& AddData (const A &a)
{
l1.push_back(make_shared<A>(a));
return (*this);
}
Data& AddData (const B &b)
{
l1.push_back(make_shared<B>(b));
return (*this);
}
private:
list<shared_ptr<Abstract>> l1;
string name;
};
class Data
{
public:
Data(const string & name) : name (name) {}
template<typename T>
Data& AddData (const T &a)
{
l1.push_back(make_shared<T>(a));
return (*this);
}
private:
list<shared_ptr<Abstract>> l1;
string name;
};