@lishuhuakai
2015-05-21T17:40:01.000000Z
字数 2215
阅读 1518
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 = 37f9fb
foo析构函数
addr = 37f9fb
Hello,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 = 002EFA1F
Hello,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 = 001CF8EB
foo拷贝析构函数
addr = 001CF9DF
foo析构函数
addr = 001CF8EB
&f = 001CF9DF
Hello,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 = 004FF797
foo构造函数
addr = 004FF68F
foo拷贝析构函数
addr = 004FF6CB
foo析构函数
addr = 004FF68F
=操作
addr = 004FF797
foo析构函数
addr = 004FF6CB
&f = 004FF797
Hello,Demo!
foo析构函数
addr = 004FF797
*/
run
函数返回了一个临时对象,foo f; f = run();
这一句自然会调用=
操作,然后临时变量立刻析构掉。