(C++ 继承)在 stl 容器中存储具有共同父对象的对象

Posted

技术标签:

【中文标题】(C++ 继承)在 stl 容器中存储具有共同父对象的对象【英文标题】:(C++ inheritance) storing objects with common parent in stl container 【发布时间】:2014-08-26 13:09:01 【问题描述】:

我在 stl 容器(实际上是堆栈)中存储了一个具有公共父级的对象,但是在其中调用一个虚函数会导致在这个公共父级中调用一个实现。见演示代码:

#include <iostream>
#include <stack>

using namespace std;

class Z

        public:
                virtual void echo()
                
                        cout << "this is Z\n";
                
                int x;
;

class A: public Z

        public:
                virtual void echo()
                
                        cout << "this is A\n";
                
;

int main()

        A a;
        a.x = 0;
        Z z;
        z.x = 100;
        stack<Z> st;

        st.push(a);
        st.top().echo(); // prints "This is Z"
        cout << "x = " << st.top().x << endl; // prints 0

        st.push(z);
        st.top().echo();  // prints "This is Z"
        cout << "x = " << st.top().x << endl; // prints 100

        return 0;

【问题讨论】:

使用std::stack&lt;Z*&gt; 避免切片。 (或std::stack&lt;std::unique_ptr&lt;Z&gt;&gt;)。 【参考方案1】:

一般来说,对象容器和多态性不会混合在一起:当您将 A 类型的对象推入容器时,您会将它们 切片Z 类型的对象(因为容器真的期待和存储sizeof(Z)的对象)

使用std::stack&lt;Z*&gt;std::stack&lt;std::unique_ptr&lt;Z&gt;&gt; 来操作指向您的基类的指针。


另请参阅:What is the slicing problem in C++?

【讨论】:

【参考方案2】:

你有slicing:

您应该使用std::stack&lt;Z*&gt;std::stack&lt;std::unique_ptr&lt;Z&gt;&gt;

【讨论】:

【参考方案3】:

你观察到的是切片。您的堆栈存储Z 对象,因此即使您构造了一个A 对象,它也不会存储在堆栈中 - 一个Z 对象将从A 构造并存储。

如果你想要多态,你不能按值存储在容器中。使用stack&lt;unique_ptr&lt;Z&gt;&gt;

【讨论】:

以上是关于(C++ 继承)在 stl 容器中存储具有共同父对象的对象的主要内容,如果未能解决你的问题,请参考以下文章

C++ STL multiset容器

具有单个键的多个值的STL集合

C++之STL

如何选出最适合的C++ STL容器?

C++ :1STL 的容器概述array容器详解迭代器初步分析

C++提高编程STL-list容器