存储基础对象和派生对象混合的容器?

时间:2012-09-02 08:58:06

标签: c++ inheritance

正确的做法是什么?我知道如果容器是基类值类型,那么存储的派生对象是“切片”。如果container是派生类类型,则无法存储基类对象。正确?

如果要使用指针,则无法使用auto_ptr,因为它具有复制语义问题。 shared_ptr是处理这个问题的唯一解决方案吗?

是否有人可以提供解决此问题的更多详细信息,示例代码或在线文章?这应该是一个很常见的问题,但我没有在教科书或网上找到太多关于它的信息。

提前致谢。

不过,我只是搜索unique_ptr。它似乎不支持复制语义。因此,在STL中使用auto_ptr只是安全吗,但可能由于缺少复制语义,许多STL操作或算法不能用于unique_ptr的容器?

4 个答案:

答案 0 :(得分:5)

如果你想要多态行为(并且你确实想要它),那么你必须使用指针或引用。许多地方都有很好的记录。

由于你不能使用引用容器,你必须使用指针容器。

现在,您可以使用您认为合适的任何类型的指针:unique_ptrshared_ptr或原始指针。

答案 1 :(得分:2)

最明显的解决方案是使用std::unique_ptr

class IBase {};
class Derived : virtual public IBase {};
std::vector<std::unique_ptr<IBase>> v;
v.push_back(std::unique_ptr<IBase>(new Derived())); 

您可以使用std::shared_ptr,但它的所有权语义会显着改变程序的行为,使动态分配的对象保持活动状态,直到没有人持有对它们的引用。

答案 2 :(得分:2)

有std :: vector和std :: shared_ptr的例子。我想这就是你想要的。

#include <iostream>
#include <memory>
#include <vector>

class Base {
public:
   virtual void foo() {
      std::cout << "base" << std::endl;
   }
};

class Derived : public Base {
   void foo() {
      std::cout << "derived" << std::endl;
   }
};

int main()
{
   std::vector<std::shared_ptr<Base> > v;
   v.push_back(std::shared_ptr<Base>(new Base));
   v.push_back(std::shared_ptr<Base>(new Derived));

   for (auto it : v) {
      it->foo();
   }
}

答案 3 :(得分:0)

[http://www.boost.org/doc/libs/1_51_0/libs/ptr_container/doc/ptr_container.html](Boost指针容器库)就是为此而做的。