如何将值添加到list< shared_ptr< Abstract>> [英] How to add values to list<shared_ptr<Abstract>>

查看:132
本文介绍了如何将值添加到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&lt; shared_ptr&lt; Abstract&gt;&gt;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆