C++中类内未初始化的对象指针为何能调用类成员函数?
问题描述
运行下述C++程序时代码可正常执行,但存在疑问:代码中bb类的成员objectaa是未做任何初始化的Aa类对象指针,为何仍能成功调用Aa类的dummyfn成员函数?
测试代码如下:
#include<bits/stdc++.h> using namespace std; class Aa { public: int a; void dummyfn (string ss); }; void Aa::dummyfn(string ss) { cout<<"calling fun from Aa "<<ss<<endl; } class bb { public: int b; Aa *objectaa; void bbfun(); }; void bb::bbfun() { cout<<"calling the bb function"<<endl; string str = "ffff"; objectaa->dummyfn(str); } int main() { bb *objectb = new bb(); objectb->bbfun(); return 0; }
原因解析
这种“正常运行”本质是C++未定义行为的巧合表现,不是代码合法的证明,核心逻辑如下:
- C++的非虚成员函数调用,底层会被编译器改写为传入隐式
this指针的普通函数调用。你写的dummyfn函数体内完全没有访问Aa类的实例成员,既没有读写成员变量a,也没有调用依赖实例状态的其他方法,整个执行过程根本不会解引用传入的this指针(也就是那个未初始化的野指针objectaa)。只要不解引用这个无效指针,就不会触发内存访问违规,自然看起来像是“调用成功”。 - 你通过
new bb()创建bb实例时,objectaa作为原生指针成员并没有被指向合法的Aa对象,存的是随机的野地址值。只是当前场景下函数执行没用到这个地址指向的内存,所以没有触发崩溃。
这类代码存在极高的风险:只要你在
dummyfn里加入任何访问实例成员的逻辑,比如打印成员变量a的值,程序大概率会立刻触发段错误;哪怕当前环境下能跑通,换编译器版本、调整编译优化选项、更换运行环境都可能出现任意不可预期的结果,绝对不能在正式代码中保留这种写法。
内容的提问来源于stack exchange,提问作者sai akash
相关产品推荐
相关产品推荐

