Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何向列表中添加值<;共享\u ptr<;摘要>&燃气轮机;_C++_List_Polymorphism_Abstract Class_Shared Ptr - Fatal编程技术网

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;
};