shared_ptr找不到虚方法

时间:2013-11-26 14:05:01

标签: c++ shared-ptr

我有一个abstact基类,它在它的构造函数中调用一个虚方法。传递基类的shared_ptr后,找不到该方法的实现。

class a 
{
 public:
   a() { fill(); }
 protected:
   virtual void fill() = 0;
}

class b : public a
{
public:
   b() : a();
protected:
   virtual void fill() { // do something }
} 
....

shared_ptr<a> sptr = shared_ptr<a> ( new b()): // error happens here on runtime

执行此操作时,我得到一个SIGABRT因为它试图执行virtual void fill() = 0;

3 个答案:

答案 0 :(得分:7)

您无法从构造函数中调用纯虚函数。在构造函数运行时,该对象被认为是正在构造的类型,而不是任何派生类型。这意味着虚拟调度在正在构造的类型中“停止”。

这意味着从fill()的构造函数调用a将尝试调用a::fill(),无论此a子对象可以属于哪个派生类。这当然失败了,因为函数没有实现。


此外,正如@KerrekSB指出的那样,您的类需要一个虚拟析构函数。否则,如果delete b实例通过指向a的指针{(很可能在涉及shared_ptr<a>时),您将得到未定义的行为。

UPDATE 显然,shared_ptr能够使用默认的删除器属性来解决虚拟析构函数的必要性,因此您的类在技术上可以没有。但是,如果没有虚拟析构函数,那么您的课程取决于仅在std::shared_ptr中进行管理;如果你改变了那一点设计,你就会遇到麻烦(而且不会立即显而易见)。因此,我建议有一个虚拟的析构函数。

答案 1 :(得分:1)

"Never Call Virtual Functions during Construction or Destruction"

您可以使用std::make_shared

shared_ptr<a> sptr = std::make_shared<b>();

答案 2 :(得分:0)

您不应该从构造函数调用虚函数。读这个: https://stackoverflow.com/a/962148/1380817