我可以有多值容器与值语义在C ++ 11? [英] Can I Have Polymorphic Containers With Value Semantics in C++11?

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

问题描述

这是相关文章问了一个永恒的问题:

This is a sequel to a related post which asked the eternal question:


我可以在C ++中使用值语义的多态容器吗?

Can I have polymorphic containers with value semantics in C++?

问题略有不正确。它应该更像:

The question was asked slightly incorrectly. It should have been more like:


我可以使用存储by-value的基类型的STL容器,其中元素显示多态行为吗?

Can I have STL containers of a base type stored by-value in which the elements exhibit polymorphic behavior?

如果您使用C ++提出问题,答案是否。在某些时候,你将分割由值存储的对象。

If you are asking the question in terms of C++, the answer is "no." At some point, you will slice objects stored by-value.

现在我再次问这个问题,但严格来说就是C ++ 11。随着对语言和标准库的更改,现在是否可以通过值在STL容器中存储多态对象?

Now I ask the question again, but strictly in terms of C++11. With the changes to the language and the standard libraries, is it now possible to store polymorphic objects by value in an STL container?

我很清楚在容器中存储一个指向基类的智能指针的可能性 - 这不是我要找的,因为我试图在堆栈上构造对象,而不使用 new

I'm well aware of the possibility of storing a smart pointer to the base class in the container -- this is not what I'm looking for, as I'm trying to construct objects on the stack without using new.

将(从链接的帖子)作为基本C ++示例:

Consider if you will (from the linked post) as basic C++ example:

#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

}


推荐答案

为了有趣,基于James关于基于模板的系统的评论,我想出了这个Vector类的实现缺少大量的功能,可能是错误的,但它是一个开始!

Just for fun, based on James's comment about a template-based system, I came up with this Vector-like implementation. It's missing lots of features, and may be buggy, but it's a start!

#include <iostream>
#include <vector>
#include <boost/shared_ptr.hpp>

template <typename T>
class Vector
{
public:
    T &operator[] (int i) const { return p[i]->get(); }
    template <typename D>
    void push_back(D &x) { p.push_back(ptr_t(new DerivedNode<D>(x))); }

private:
    class Node
    {
    public:
        virtual T &get() = 0;
    };

    template <typename D>
    class DerivedNode : public Node
    {
    public:
        DerivedNode(D &x) : x(x) {}
        virtual D &get() { return x; }
    private:
        D x;
    };

    typedef boost::shared_ptr<Node> ptr_t;
    std::vector<ptr_t> p;
};

///////////////////////////////////////

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

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

        int child_mem;
};


int main()
{
    Vector<Parent> v;

    v.push_back(Parent());
    v.push_back(Child());

    v[0].write();
    v[1].write();
}

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

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