我可以在C ++中使用值语义的多态容器吗? [英] Can I have polymorphic containers with value semantics in C++?

查看:93
本文介绍了我可以在C ++中使用值语义的多态容器吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

作为一般规则,我喜欢在C ++中使用值而不是指针语义(即使用向量< Class> 而不是向量& > )。通常,由于不必记住删除动态分配的对象,性能上的轻微损失就会大于弥补。



不幸的是,存储所有派生自公共基础的各种对象类型。请参阅下面的示例。

  #include< iostream& 

using namespace std;

class Parent
{
public:
Parent():parent_mem(1){}
virtual void write(){cout< Parent:<< parent_mem<< endl; }
int parent_mem;
};

class Child:public Parent
{
public:
Child():child_mem(2){parent_mem = 2; }
void write(){cout<< Child:<< parent_mem<< ,< child_mem<< endl; }

int child_mem;
};

int main(int,char **)
{
//我可以有一个具有指针语义的多态容器
vector< Parent *> pointerVec;

pointerVec.push_back(new Parent());
pointerVec.push_back(new Child());

pointerVec [0] - > write();
pointerVec [1] - > write();

//输出:
//
//父级:1
//子级:2,2

//但是不能用价值语义来做它

vector< Parent> valueVec;

valueVec.push_back(Parent());
valueVec.push_back(Child()); //变成父对象:

valueVec [0] .write();
valueVec [1] .write();

输出:
//
//父级:1
//父级:2

}

我的问题是:我可以有我的蛋糕(值语义),也吃它(多态容器)?或者我必须使用指针吗?

$因为不同类的对象将有不同的大小,所以如果将它们存储为值,那么最终会进入切片问题。

>

一个合理的解决方案是存储容器安全的智能指针,我通常使用boost :: shared_ptr,这是安全地存储在一个容器中注意std :: auto_ptr不是。 p>

  vector< shared_ptr< Parent>> vec; 
vec.push_back(shared_ptr< Parent>(new Child );

shared_ptr使用引用计数,因此在删除所有引用之前,不会删除底层实例。 / p>

As a general rule, I prefer using value rather than pointer semantics in C++ (ie using vector<Class> instead of vector<Class*>). Usually the slight loss in performance is more than made up for by not having to remember to delete dynamically allocated objects.

Unfortunately, value collections don't work when you want to store a variety of object types that all derive from a common base. See the example below.

#include <iostream>

using namespace std;

class Parent
{
    public:
        Parent() : parent_mem(1) {}
        virtual void write() { cout << "Parent: " << parent_mem << endl; }
        int parent_mem;
};

class Child : public Parent
{
    public:
        Child() : child_mem(2) { parent_mem = 2; }
        void write() { cout << "Child: " << parent_mem << ", " << child_mem << endl; }

        int child_mem;
};

int main(int, char**)
{
    // I can have a polymorphic container with pointer semantics
    vector<Parent*> pointerVec;

    pointerVec.push_back(new Parent());
    pointerVec.push_back(new Child());

    pointerVec[0]->write(); 
    pointerVec[1]->write(); 

    // Output:
    //
    // Parent: 1
    // Child: 2, 2

    // But I can't do it with value semantics

    vector<Parent> valueVec;

    valueVec.push_back(Parent());
    valueVec.push_back(Child());    // gets turned into a Parent object :(

    valueVec[0].write();    
    valueVec[1].write();    

    // Output:
    // 
    // Parent: 1
    // Parent: 2

}

My question is: Can I have have my cake (value semantics) and eat it too (polymorphic containers)? Or do I have to use pointers?

解决方案

Since the objects of different classes will have different sizes, you would end up running into the slicing problem if you store them as values.

One reasonable solution is to store container safe smart pointers. I normally use boost::shared_ptr which is safe to store in a container. Note that std::auto_ptr is not.

vector<shared_ptr<Parent>> vec;
vec.push_back(shared_ptr<Parent>(new Child()));

shared_ptr uses reference counting so it will not delete the underlying instance until all references are removed.

这篇关于我可以在C ++中使用值语义的多态容器吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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