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

将父类reinterpret_cast为子类后,父类函数能否调用子类函数?

问题解答

首先必须明确:你用reinterpret_cast<B*>(ab)把实际类型为A的对象指针强转为B*,这属于C++标准定义的未定义行为——也就是说,这么做之后任何操作的结果都是不可预测的,编译器和运行环境没有义务保证代码按你预期工作,本质上是错误的写法。

当前调用bab->func1()输出class A的原因很简单:func2是虚函数,虚函数的调用基于对象实际的虚表。你创建的对象是A类型,它的虚表中func2对应的就是A::func2,不管你把指针转成什么类型,虚函数调用都会指向实际对象的虚表条目,所以还是会执行A::func2。

关于你要的“无需重定义func1”的实现方式

不存在标准、安全且可移植的方法能实现这个需求,因为你的核心操作(把A对象当成B对象用)本身就违反了C++的类型系统规则。

如果非要强行达到这个效果(强烈不推荐,仅作为技术探讨),可以尝试手动修改对象的虚表指针,但这完全依赖编译器的虚表实现(比如GCC/Clang和MSVC的虚表结构就不一样),而且会带来严重的内存安全问题和移植性问题。示例代码(仅适用于GCC/Clang,无任何安全性保证):

#include <iostream>

class A {
public:
    void func1() {
        func2();
    }
protected:
    virtual void func2() {
        printf("class A\n");
    }
};

class B : public A {
protected:
    virtual void func2() {
        printf("class B\n");
    }
};

// 获取类的虚表地址(仅GCC/Clang有效)
template<typename T>
void** get_vtable(T* obj) {
    return *reinterpret_cast<void***>(obj);
}

int main() {
    A* ab = new A();
    ab->func1(); // 输出class A

    B temp_b;
    void** b_vtable = get_vtable(&temp_b);
    // 修改A对象的虚表指针为B的虚表
    *reinterpret_cast<void***>(ab) = b_vtable;

    B* bab = reinterpret_cast<B*>(ab);
    bab->func1(); // 此时会输出class B,但属于未定义行为

    delete ab;
    return 0;
}

正确的做法

如果你需要调用B::func2,应该直接创建B类型的对象,利用C++正常的多态机制:

int main() {
    A* ab = new B(); // 父类指针指向子类对象
    ab->func1(); // 自动输出class B,无需重定义func1
    delete ab;
    return 0;
}

这才是符合C++类型系统和多态设计的正确写法,安全且可移植。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 20:01:06