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

C++父类指针数组存子类实例,调用printall异常,求错误原因

问题分析:子类对象指针数组调用成员函数异常的原因

你遇到的问题核心是数组的传递和访问方式错误,加上可能缺少虚函数的定义,导致内存访问越界或者调用了错误的函数版本。咱们一步步拆解:

先看你代码里的关键问题点

首先是你的printall方法调用和实现:

// 调用时传了*CA
p.printall(*CA, (size));

// printall的实现
void Print::printall(CompressionAlgorithm *ca, int size) {
    for (int i = 0; i < size; i++) {
        cout << i+1 << " for ";
        cout << ca[i].GetName(); // 这里用了.访问,而ca[i]是错误的对象
        cout << "\n";
    }
}

你定义的CA是CompressionAlgorithm *CA[size],也就是一个指针数组,每个元素是指向子类对象的父类指针。但你调用printall时传了*CA,这等价于传了CA[0]——也就是第一个子类对象的指针。

然后在printall里,ca[i]会被编译器解释为:从ca的地址开始,偏移i * sizeof(CompressionAlgorithm)字节的位置,把那块内存当作一个CompressionAlgorithm对象。但实际上,你的数组里存的是指针(每个指针占8字节,64位系统),不是对象本身!这样ca[1]就会访问到CA[0]指向的对象内存后面的区域,完全不是CA[1]的地址,自然会触发内存访问错误(比如std::bad_alloc)或者无输出。

另外还有一个潜在问题:如果父类CompressionAlgorithm的GetName不是虚函数,那么即使你访问到了正确的对象,也会调用父类的GetName(如果父类有实现),而不是子类的版本。

正确的解决步骤

  1. 确保父类的GetName是虚函数,并且添加虚析构
    这是多态的基础,必须让父类的成员函数成为虚函数,才能通过父类指针调用子类的实现。同时虚析构能避免内存泄漏:

    class CompressionAlgorithm {
    public:
        // 纯虚函数,强制子类实现GetName
        virtual std::string GetName() const = 0;
        // 虚析构,确保删除子类对象时正确调用析构函数
        virtual ~CompressionAlgorithm() = default;
    };
    
  2. 修改printall的参数和访问方式
    我们需要接收指针数组(也就是CompressionAlgorithm**类型),然后用->访问成员函数,因为数组元素是指针:

    void Print::printall(CompressionAlgorithm** ca, int size) {
        for (int i = 0; i < size; i++) {
            cout << i+1 << " for ";
            cout << ca[i]->GetName(); // 用->访问指针指向的对象的成员
            cout << "\n";
        }
    }
    
  3. 修改调用方式
    直接传数组名CA即可,因为数组名会退化为指向第一个元素的指针(也就是CompressionAlgorithm**类型):

    Print p;
    p.printall(CA, size);
    

为什么这样能解决问题?

  • 传CA而不是*CA,让printall拿到的是指针数组的首地址,ca[i]就能正确访问到第i个指向子类对象的指针。
  • 用->访问成员函数,加上父类的虚函数定义,就能触发多态,正确调用子类的GetName实现。
  • 虚析构保证后续用delete CA[i]时,能正确释放子类对象的内存。

内容的提问来源于stack exchange,提问作者Kartin Palacinka

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:35:36