【问题标题】:What is the meaning of a "pure virtual" call in a stack trace?堆栈跟踪中的“纯虚拟”调用是什么意思?
【发布时间】:2014-04-05 18:07:09
【问题描述】:

我的服务崩溃了,我得到了这个堆栈跟踪。我无法从这里推断出任何东西

00007f859cd27834 __gnu_cxx::__verbose_terminate_handler()
@ 00007f859cd25865 __cxxabiv1::__terminate(void (*)())
@ 00007f859cd25892 std::terminate()
@ 00007f859cd263be __cxa_pure_virtual
@ 0000000001996f9f My::Class::~Class()

谁能帮忙?

【问题讨论】:

  • Class 的析构函数是问题所在。你还想要别的吗?
  • OP调用了一个在orent类析构函数中的子类中定义的虚函数?
  • 不知道你是谁,但 可以推断出有人可能不知道从构造函数或析构函数调用虚函数的实际作用。
  • n.m. - 如何调用纯虚函数?
  • @jww 如果确实没有实现,那么这正是它崩溃的原因。一个纯虚函数实际上可以有一个实现。

标签: c++ c debugging gcc gdb


【解决方案1】:

如果实际上调用了“纯虚拟”函数,就会发生这种情况,这会导致崩溃。

一个纯虚函数是声明的:

virtual void pureVirtualFunction() = 0;

通常编译器会检测你是否省略实现纯虚函数。但在某些情况下它不能。

基构造函数中纯虚函数的调用

一个常见的问题是从类的基本构造函数调用函数:

MyClass::MyClass() { 
    pureVirtualFunction(); // Call of pure virtual function from base constructor.
}

基解构器中纯虚函数的调用

或者从基类的解构器调用纯虚方法:

MyClass::~MyClass() { 
    pureVirtualFunction(); // Call of pure virtual function from base deconstructor.
}

共享指针的前向声明(和类似的)

如果您使用这样的前向声明,还有另一种常见情况:

class MyClass;
typedef std::shared_ptr<MyClass> MyClassPtr;

这种共享指针的对象可以在很多地方被销毁,但是编译器缺少如何调用类的解构器所需的信息。确保您阅读编译器的所有警告,它会警告这个问题(以及调用纯虚方法的许多其他问题。)

对于这种特殊情况,请确保避免共享指针的前向声明,并且仅将它们包含在类声明中(如果可能)。

另请参阅answer

【讨论】:

    【解决方案2】:

    或者更有可能:

    virtual ~Class () = 0;
    

    这声明了一个虚拟析构函数并告诉编译器在 vtable 中为析构函数腾出空间。但由于没有定义,GCC 在 vtable 中插入了对 __cxa_pure_virtual 的调用。

    当您未能为 ~Class() 定义主体或未能在派生类中显式编写主体时,您将在销毁时调用 __cxa_pure_virtual。

    在尝试实例化抽象类时,您应该收到某种警告或错误。

    再往上看一点,实际上可能会提供更多关于问题所在的证据。并且代码示例演示您如何使用该类可能会很有用。

    【讨论】:

    • 是的,一定是这种情况。编译时应该有警告。一个常见的问题是使用前向声明,例如std::shared_ptr.
    • 一个带有未定义的纯虚析构函数won't link的程序。
    猜你喜欢
    • 1970-01-01
    • 2015-05-14
    • 2011-01-06
    • 1970-01-01
    • 2011-09-13
    • 2019-06-30
    • 2011-11-09
    • 2020-06-26
    相关资源
    最近更新 更多