c ++在std :: shared_ptr <baseclass> </baseclass>中使用派生类

时间:2013-12-04 14:03:14

标签: c++11 shared-ptr

我有以下结构:

class A 
{
   A(const A&) {...}
   virtual int member() = 0;
   virtual ~A() {}; 
}

class B : public A 
{ 
   virtual int member(){... }  
   virtual ~B(){}
}

class C : public A 
{
   virtual int member(){... }  
   virtual ~C(){}
} 

并使用std::shared_ptr<A>作为我工厂的返回类型。

std::shared_prt<A> Factory::get(params...)
{
   ...

   return std::make_shared<B>(params);
}

std::shared_ptr<A> Aptr = Factory::get(params...) 

现在我尝试将其传递给外部方法:

boost::iostreams::filtering_istream

void push( const T& t,
           std::streamsize buffer_size = default value,
           std::streamsize pback_size = default value );

此调用在编译时失败,因为some_external_function尝试调用A的纯member()而不是B。

concept_adapter.hpp:122:错误:无法将字段'boost :: iostreams :: detail :: concept_adapter :: t_'声明为抽象类型'A'

1 个答案:

答案 0 :(得分:2)

在这里使用PImpl成语。

push方法要求第一个参数是可复制构造的。这意味着它被复制到Boost的内部深处。没有好处,因为你不能复制多态对象,它会被切片。

解决方案是拥有一个非多态类APimpl,它将指针(共享,唯一或原始,您决定)保存到A,并转发对该指针的调用。它可以自由复制,不会产生切片效果。

class APimpl
{
   public:
     APimpl(std::shared_ptr<A> a) : p_a(a) {}
     // compiler-generated copy ctor and assignment are OK here
     void method() { p_a->method(); }
   private:
     std::shared_ptr<A> p_a; 
};

您可能需要在clone中使用A方法并在复制APimpl时使用该方法,或者在A的多个实例之间共享APimpl 。你想要哪一个取决于A的作用。我的例子演示了第二种情况。