为何通过纯虚基类指针调用方法会触发段错误?
问题解析:抽象基类指针调用具体方法触发段错误
核心原因
你的**DataCallback_Actual类未继承DataCallback抽象基类**,这是段错误的根本原因:
- 直接用
pDataCallbackTwo_A调用Callback时,属于普通成员函数调用,不需要访问虚表,因此能正常执行。 - 强制将
pDataCallbackTwo_A转换为DataCallback*后调用Callback,程序会尝试访问虚表(因为DataCallback中的Callback是纯虚函数),但DataCallback_Actual没有虚函数,也未继承带虚函数的类,不存在虚表,因此访问非法内存触发段错误。
修正代码
只需让具体类正确继承抽象基类,并规范重写虚函数:
#include <iostream> enum Result_t { SUCCESS }; class DataCallback { public: virtual Result_t Callback(int32_t data) = 0; virtual ~DataCallback(){} }; // 公开继承抽象基类 class DataCallback_Actual : public DataCallback { public: // 用override明确标记重写虚函数(可选但推荐) Result_t Callback(int32_t data) override { std::cout << m_name << ": int data update: " << data << std::endl; return SUCCESS; } DataCallback_Actual(const std::string & name): m_name(name) { std::cout << "constructor DataCallback_Actual::DataCallback_Actual(" << m_name << ") @ 0x" << std::hex << this << std::endl; } private: std::string m_name; }; int main(int argv, char **argc) { DataCallback_Actual * pDataCallbackTwo_A = new DataCallback_Actual(std::string("Object-Two-Int")); // 多态场景下无需强制转换,直接赋值即可 DataCallback * pDataCallbackTwo = pDataCallbackTwo_A; pDataCallbackTwo_A->Callback(10); pDataCallbackTwo->Callback(12); // 释放内存避免泄漏 delete pDataCallbackTwo_A; return 0; }
关于另一组正常运行的说明
如果另一组抽象/具体类对能正常运行,必然是因为具体类正确继承了抽象基类,符合C++多态的要求;若存在未继承却运行正常的情况,属于未定义行为(类布局巧合匹配),完全不可靠。
内容的提问来源于stack exchange,提问作者D M Lowe
相关产品推荐
相关产品推荐

