为何用A类对象指针调用B类成员函数不触发异常?
问题描述
给出如下C++代码:
struct A { bool testA(int) { std::cout << "A" << std::endl; return true; }; }; struct B { void testB() { std::cout << "B" << std::endl; }; }; int main() { A a; ((B*)(&a))->testB(); return 0; }
通过强制类型转换将A类对象指针转换为B类指针后调用B类的testB成员函数,为何未抛出异常?
解答
这本质是因为C++的非虚成员函数调用是静态绑定的,且这段代码的行为属于「未定义行为」——只是它刚好没触发崩溃或异常而已,绝非合法操作。具体原因拆解:
- 非虚成员函数的调用地址是编译期就确定的,编译器不会在运行时检查指针指向对象的实际类型。
testB是B的非虚成员函数,编译((B*)(&a))->testB()时,编译器直接生成调用B::testB的指令,完全不会验证指针指向的是不是真正的B对象。 testB的实现里没有访问任何类成员变量,只是执行字符串输出操作,它不需要依赖B对象的内存数据。所以即便指向的是A对象的内存,函数执行时也不会触发内存访问错误。如果testB里有访问B的成员变量,大概率会直接崩溃或出现诡异行为,但这依然属于未定义行为,不是必然会抛出异常。- C++本身不会为这种非法类型转换自动抛出异常,除非你手动在代码中添加了异常检查逻辑。C风格强制转换
(B*)本身就是在告诉编译器「我清楚自己的操作,无需拦截」,所以编译器不会帮你做运行时类型校验。
内容的提问来源于stack exchange,提问作者user12660456
相关产品推荐
相关产品推荐

