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

C++ 子类实例赋值给父类变量后无法调用虚函数重写版本如何解决

问题根因

你当前代码里B test = C();的写法触发了对象切片:当你直接将派生类实例赋值给基类的栈对象时,派生类中不属于基类的部分(包括C类的虚表指针、独有成员)会被截断丢弃,最终test本质是一个纯B类实例,虚函数调用自然只会走到A的实现。

解决方案

要保留多态特性,必须通过基类指针或者基类引用来持有派生类实例,不能直接用基类值类型存储。

方案1:使用基类指针

你可以用普通指针或者智能指针来持有实例,避免对象切片,示例代码如下:

#include <iostream>
// 智能指针需要引入的头文件
#include <memory>

class  A
{
public:
    A(/* args */){};
    virtual void p(){std::cout << "A\n";}
    // 存在继承关系的基类建议添加虚析构函数,避免内存泄漏
    virtual ~A() = default;
};

class  B : public A
{
public:
    B(/* args */){};
};

class  C : public B
{
public:
    C(/* args */){};
    void p() override{std::cout << "C\n";}
};

int main(int argc, char const *argv[])
{
    // 智能指针写法,无需手动释放内存
    std::unique_ptr<B> test = std::make_unique<C>();
    // 普通指针写法:B* test = new C();
    C test2 = C();

    test->p(); 
    test2.p();

    // 普通指针需要手动释放内存:delete test;
    return 0;
}

方案2:使用基类引用

如果派生类实例的生命周期和引用的作用域一致,也可以用基类引用绑定派生类实例:

int main(int argc, char const *argv[])
{
    C c_inst;
    B& test = c_inst;
    C test2 = C();

    test.p();
    test2.p();
    return 0;
}

两种方案修改后运行输出均为:

C
C

符合你的需求。

内容的提问来源于stack exchange,提问作者Jonathan Layduhur

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 19:45:02