You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何通过纯虚基类指针调用方法会触发段错误?

问题解析:抽象基类指针调用具体方法触发段错误

核心原因

你的**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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 14:31:51