[ 2007/10/10 06:55 | by turbozv ]
|
阅读以下程序,写出输出结果:
很奇怪是吧,我也从来没有这样这样使用过栈对象。
我们知道,使用栈对象的好处就是编译器会在该对象生存期结束的时候自动帮我们调用它的析构函数,这就是Smart Pointer(智能指针)的理论依据。
在这个题目中,用指针p和引用a分别指向了两个栈上的临时对象A(1)和A(2),编译器将会怎样去处理它们呢?
对于临时对象A(1),它的地址被赋值给了p,然后就再也没有用了,编译器无法跟踪这个对象,于是只能在赋值以后立刻调用~A()(不然的话就没有办法释放了)
对于临时对象A(2),它被a引用,a是一个栈变量,所以可以被记录,因此~A()的调用就会在return之后。
大家看看汇编的结果吧(VS2005, 关闭Optimization,关闭Buffer Security Check)
你明白了么?来做到题目试试吧
引用
class A {
private:
int _x;
public:
A(int x) {
_x = x;
printf("A(%d)\n", _x);
}
~A() {
printf("~A(%d)\n", _x);
}
};
void main()
{
A *p = &A(1);
A &a = A(2);
return;
}
private:
int _x;
public:
A(int x) {
_x = x;
printf("A(%d)\n", _x);
}
~A() {
printf("~A(%d)\n", _x);
}
};
void main()
{
A *p = &A(1);
A &a = A(2);
return;
}
很奇怪是吧,我也从来没有这样这样使用过栈对象。
我们知道,使用栈对象的好处就是编译器会在该对象生存期结束的时候自动帮我们调用它的析构函数,这就是Smart Pointer(智能指针)的理论依据。
在这个题目中,用指针p和引用a分别指向了两个栈上的临时对象A(1)和A(2),编译器将会怎样去处理它们呢?
对于临时对象A(1),它的地址被赋值给了p,然后就再也没有用了,编译器无法跟踪这个对象,于是只能在赋值以后立刻调用~A()(不然的话就没有办法释放了)
对于临时对象A(2),它被a引用,a是一个栈变量,所以可以被记录,因此~A()的调用就会在return之后。
大家看看汇编的结果吧(VS2005, 关闭Optimization,关闭Buffer Security Check)
引用
void main()
{
00401830 push ebp
00401831 mov ebp,esp
00401833 sub esp,10h
A *p = &A(1);
00401836 push 1
00401838 lea ecx,[ebp-10h]
0040183B call A::A (401000h)
00401840 mov dword ptr [p],eax
00401843 lea ecx,[ebp-10h]
00401846 call A::~A (401030h)
A &a = A(2);
0040184B push 2
0040184D lea ecx,[ebp-0Ch]
00401850 call A::A (401000h)
00401855 lea eax,[ebp-0Ch]
00401858 mov dword ptr [a],eax
return;
0040185B lea ecx,[ebp-0Ch]
0040185E call A::~A (401030h)
}
{
00401830 push ebp
00401831 mov ebp,esp
00401833 sub esp,10h
A *p = &A(1);
00401836 push 1
00401838 lea ecx,[ebp-10h]
0040183B call A::A (401000h)
00401840 mov dword ptr [p],eax
00401843 lea ecx,[ebp-10h]
00401846 call A::~A (401030h)
A &a = A(2);
0040184B push 2
0040184D lea ecx,[ebp-0Ch]
00401850 call A::A (401000h)
00401855 lea eax,[ebp-0Ch]
00401858 mov dword ptr [a],eax
return;
0040185B lea ecx,[ebp-0Ch]
0040185E call A::~A (401030h)
}
你明白了么?来做到题目试试吧
引用
请输出程序运行结果:
class A {
private:
int _x;
public:
A(int x) {
_x = x;
printf("A(%d)\n", _x);
}
~A() {
printf("~A(%d)\n", _x);
}
void set(int x) {
_x = x;
}
int get() {
return _x;
}
};
void main()
{
A &a = A(1);
A *p = &A(2);
p->set(3);
a.set(4);
printf("%d\n%d\n", p->get(), a.get());
return;
}
class A {
private:
int _x;
public:
A(int x) {
_x = x;
printf("A(%d)\n", _x);
}
~A() {
printf("~A(%d)\n", _x);
}
void set(int x) {
_x = x;
}
int get() {
return _x;
}
};
void main()
{
A &a = A(1);
A *p = &A(2);
p->set(3);
a.set(4);
printf("%d\n%d\n", p->get(), a.get());
return;
}
这个是错误的用法,GCC下无法通过编译,VC++下没试过