c++ 如何捕获一个名为error的纯虚方法?

noj0wjuj  于 2023-06-25  发布在  其他
关注(0)|答案(2)|浏览(170)

我偶尔会得到这个错误

pure virtual method called
terminate called without an active exception

1.在C++中示例化抽象类是不可能的,那么怎么可能出现这种情况呢
1.我如何追踪这个错误?这里的复杂之处在于,一个进程启动子进程,因此它可以在子进程中或父进程中。
我已经在代码中添加了一些try/catch块,但是有没有一些工具可以帮助捕获这个错误?
valgrind是不能用在我的情况下,因为这是一个高速编码器与高内存使用,所以它需要永远运行。
任何提示或线索将是最受欢迎的。

pexxcrt2

pexxcrt21#

一个可能的原因是你在构造函数或析构函数中调用了一个虚成员函数,而虚函数调用还不起作用。这是因为:

  • 在构造函数中,我们还没有构造从我们继承的派生类
  • 在析构函数中,我们已经销毁了从我们继承的派生类

例如:

struct Base {
    Base() { foo(); } // undefined behavior
    virtual void foo() = 0;
};

struct Derived : Base {
    void foo() final {}
}
追踪呼叫

这通常非常容易,因为编译器通常可以检测到这一点并发出警告:

<source>:2:14: warning: call to pure virtual member function 'foo' has undefined behavior;
                        overrides of 'foo' in subclasses are not available in the
                        constructor of 'Base' [-Wcall-to-pure-virtual-from-ctor-dtor]
    Base() { foo(); }
             ^

如果由于某种原因这不起作用,我们可以使用调试器跟踪对Base::foo()的调用,并在调用std::terminate时停止它。GDB中的break abort应该可以工作,因为std::terminate默认调用std::abort
如果这是不可能的,我们可以使用std::set_terminate定义一个终止处理程序,并在其中放置一个断点。
如果出于任何原因这不是一个可用的选项(例如C++98代码库),我们可以定义Base::foo()并在其中放置断点:

void Base::foo() {
    // breakpoint here
}
polhcujo

polhcujo2#

在使用Itanium ABI的GCC/on系统中,可以定义函数__cxa_pure_virtual。当一个没有其他定义的纯虚函数被调用时,这个函数被调用。
默认情况下,它只打印“pure virtual method called”,然后终止。你可以让它抛出一个异常和堆栈跟踪,或者有一个断点:

extern "C" void __cxa_pure_virtual() {
    trap_signal();
    gdb_breakpoint();
    print_stacktrace();
    throw std::runtime_error("pure virtual function called");
}

相关问题