@lishuhuakai
2015-05-21T09:40:01.000000Z
字数 2215
阅读 1790
c++
C++真正的临时对象是不可见的匿名对象,不会出现在你的源码中,但是程序在运行时确实生成了这样的对象。
下面是一个例子:
#include <iostream>using namespace std;class foo{public:foo(){cout << "foo构造函数" << endl;printf("addr = %x\n", this);}~foo(){cout << "foo析构函数" << endl;printf("addr = %x\n", this);}};void main(){foo();printf("Hello,Demo!\n");system("pause");}/**foo构造函数addr = 37f9fbfoo析构函数addr = 37f9fbHello,Demo!*/
直接调用foo类的构造函数就会生成一个临时对象,它昙花一现,立马析构。这也说明了这个临时变量既不在堆上,也不再栈上,在哪里,我不知道。
#include <iostream>using namespace std;class foo{public:foo(){cout << "foo构造函数" << endl;cout << "addr = " << this << endl;}~foo(){cout << "foo析构函数" << endl;cout << "addr = " << this << endl;}foo(const foo &op){cout << "foo拷贝析构函数" << endl;cout << "addr = " << this << endl;}};void play(){foo f = foo();cout << "&f = " << &f << endl;printf("Hello,Demo!\n");}void main(){play();system("pause");}/**foo构造函数addr = 002EFA1F&f = 002EFA1FHello,Demo!foo析构函数addr = 002EFA1F*/
我们看到,fooo f = foo()这一句,并没有和预计的一样调用拷贝构造函数,很显然,c++在这里做了优化,c++直接将f和构造的临时变量绑定在了一起,因为他们的地址是一致的。这样做的好处是节省了一次构造和析构函数,提升了效率。
这样的话,之前困扰我的问题也很好理解了。
#include <iostream>using namespace std;class foo{public:foo(){cout << "foo构造函数" << endl;cout << "addr = " << this << endl;}~foo(){cout << "foo析构函数" << endl;cout << "addr = " << this << endl;}foo(const foo &op){cout << "foo拷贝析构函数" << endl;cout << "addr = " << this << endl;}};foo run(){foo a;return a;}void play(){foo f = run();cout << "&f = " << &f << endl;printf("Hello,Demo!\n");}void main(){play();system("pause");}/**foo构造函数addr = 001CF8EBfoo拷贝析构函数addr = 001CF9DFfoo析构函数addr = 001CF8EB&f = 001CF9DFHello,Demo!foo析构函数addr = 001CF9DF*/
run函数里定义了一个类的实体a,他返回一个foo类的对象,因为函数返回时会清空栈里的东西,因此c++会构建一个临时的变量返回,此时在play函数里有foo f = run(),这种情况和前面的类似,该临时变量和f绑定起来,提升了效率。
同理,在play函数里我们这么改动,结果是这样的:
#include <iostream>using namespace std;class foo{public:foo(){cout << "foo构造函数" << endl;cout << "addr = " << this << endl;}~foo(){cout << "foo析构函数" << endl;cout << "addr = " << this << endl;}foo(const foo &op){cout << "foo拷贝析构函数" << endl;cout << "addr = " << this << endl;}void operator = (const foo &op){cout << "=操作" << endl;cout << "addr = " << this << endl;}};foo run(){foo a;return a;}void play(){foo f;f = run();cout << "&f = " << &f << endl;printf("Hello,Demo!\n");}void main(){play();system("pause");}/**foo构造函数addr = 004FF797foo构造函数addr = 004FF68Ffoo拷贝析构函数addr = 004FF6CBfoo析构函数addr = 004FF68F=操作addr = 004FF797foo析构函数addr = 004FF6CB&f = 004FF797Hello,Demo!foo析构函数addr = 004FF797*/
run函数返回了一个临时对象,foo f; f = run();这一句自然会调用=操作,然后临时变量立刻析构掉。