Cpp下匿名对象探究
先来看看一段代码:
#include "iostream" using namespace std; class ABCD { public: ABCD(int a, int b, int c) { this->a = a; this->b = b; this->c = c; printf("ABCD() construct, a:%d,b:%d,c:%d \n", this->a, this->b, this->c); } ~ABCD() { printf("~ABCD() construct,a:%d,b:%d,c:%d \n", this->a, this->b, this->c); } int getA() { return this->a; } protected: private: int a; int b; int c; }; int run3() { printf("run3 start..\n"); ABCD(400, 500, 600); printf("run3 end\n"); return 0; } int main() { run3(); system("pause"); return 0; }
我们下断点来一步一步调试:
我们F11,进入下一步:
打印出如下:
我们继续往下走:
调用ABCD类的构造函数,完成对象的初始化工作
继续往下走,我们会发现:
跟进:
析构完成后:
输出结果:
继续往下走,程序执行完毕。
从上面我们可以分析出,匿名对象如果没有完成赋值,也就是没有与一个对象进行绑定,那么匿名对象的构造执行完毕后,会马上执行析构函数,回收对象分配的内存空间。
有了上面的基础,我们来看看匿名对象的一个经典案例:
#include "iostream" using namespace std; //构造中调用构造是危险的行为 class MyTest { public: MyTest(int a, int b, int c) { this->a = a; this->b = b; this->c = c; } MyTest(int a, int b) { this->a = a; this->b = b; MyTest(a, b, 100); //产生新的匿名对象 } ~MyTest() { printf("MyTest~:%d, %d, %d\n", a, b, c); } protected: private: int a; int b; int c; public: int getC() const { return c; } void setC(int val) { c = val; } }; int main() { MyTest t1(1, 2); printf("c:%d", t1.getC()); //请问c的值是? 输出一个垃圾值 system("pause"); return 0; }
上面函数执行结果如下:
可以看出,c的输出结果为一个垃圾值,那么为什么会出现这种情况呢?下面我们来分析一下上面的代码:
我们跟进:
完成对象的初始化,接着我们继续执行MyTest(1,2,100);,注意,这里会产生一个匿名对象,我们上面说过,当匿名对象没有进行绑定操作,会自动进行析构。所以当我们执行完上面代码后,会马上调用析构函数,回收匿名对象的内存空间。
完成对匿名函数的析构,也就是说此时匿名对象内存空间已经被回收,那么c对应值此时是系统随机分配的,所以最终的输出结果是一个垃圾值。