C++ 混合存储基本对象和派生对象的容器?

C++ 混合存储基本对象和派生对象的容器?,c++,inheritance,C++,Inheritance,正确的做法是什么?我知道,如果容器是基类值类型,则存储的派生对象是“切片的”。若容器为派生类类型,则无法存储基类对象。对吧? 如果要使用指针,则不能使用auto_ptr,因为它存在复制语义问题。共享ptr是处理此问题的唯一解决方案吗 有人能提供更多的细节、示例代码或在线文章来解决这个问题吗?这应该是一个很常见的问题,但我并没有在教科书或网上找到太多关于它的信息 提前谢谢 顺便说一句,我只是在unique_ptr上搜索。它似乎不支持复制语义。因此,在STL中使用STL不仅仅比自动ptr安全,而且可

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

如果要使用指针,则不能使用auto_ptr,因为它存在复制语义问题。共享ptr是处理此问题的唯一解决方案吗

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

提前谢谢


顺便说一句,我只是在unique_ptr上搜索。它似乎不支持复制语义。因此,在STL中使用STL不仅仅比自动ptr安全,而且可能由于缺乏复制语义,许多STL操作或算法无法在唯一的ptr容器上使用?

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

类IBase{};
派生类:虚拟公共IBase{};
std::向量v;
v、 向后推(std::unique_ptr(new-Derived());

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

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

由于不能使用引用容器,所以必须使用指针容器


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

有std::vector和std::shared\u 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();
   }
}
#包括
#包括
#包括
阶级基础{
公众:
虚拟void foo(){

标准::cout[http://www.boost.org/doc/libs/1_51_0/libs/ptr_container/doc/ptr_container.html](Boost指针容器库)就是为了这个。确实,你不能创建引用的容器。但是你可以用
std::reference\u wrapper
来伪造它。它有一个指针,但允许你通过引用来访问它。有没有办法知道一个算法是否可以安全地与
unique\u ptr
一起使用?显然,有些算法不能(
copy()
填充()
)但是,似乎有些删除或重排元素可能会或可能不,这取决于它们是如何实现的。@ PeteBecker:我尝试了容器的代码>参考文献包装器< /COD>一次,但它并没有很好地工作。问题是C++中不能超载<代码>运算符。< /Cord>,以便访问CON成员。获取的对象必须执行,例如,
c[0]。get()->member
。如果必须执行此操作,还可以执行
c[0]->成员
。这里不清楚是否需要共享所有权。我想说,除非对共享有明确的关注,否则最好使用唯一所有权。我的问题是,什么时候共享所有权是必须的?谢谢juanchopanza,你能不能详细说明一下“但它的所有权语义会显著改变程序的行为,keepin?”g…“?你的意思是,如果程序员不十分小心,使用共享的\u ptr有时会留下未使用的副本,因此对象无法及时释放;而unique \u ptr始终只有一个副本,并且没有这样的问题吗?@user1559625可能会有所帮助。基本上,unique \u ptr拥有指针对象的所有权,并在删除指针对象时将其删除。所有权可以被“感动”从一个唯一的\u ptr到另一个,但不能有多个所有者。使用共享\u ptr,可以有任意数量的所有者,最后一个所有者会删除指针对象。有时,你想知道指针对象何时被删除,有时你不在乎。我想
IBase
必须有一个虚拟析构函数。使用
shared_ptr
这不是一个问题,因为删除器的类型擦除;但是
unique_ptr
不是这样。但是你如何从中恢复原始对象?谢谢n.m.非常有用的信息。
#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();
   }
}