C++ 在C++;
考虑以下代码C++ 在C++;,c++,C++,考虑以下代码 int i; class A { public: ~A() { i=10; } }; int foo() { i=3; A ob; return i; } int main() { cout << foo() << endl; return 0; } inti; 甲级 { 公众: ~A() { i=10; } }; int foo() { i=3; 产科医生; 返回i; } int mai
int i;
class A
{
public:
~A()
{
i=10;
}
};
int foo()
{
i=3;
A ob;
return i;
}
int main()
{
cout << foo() << endl;
return 0;
}
inti;
甲级
{
公众:
~A()
{
i=10;
}
};
int foo()
{
i=3;
产科医生;
返回i;
}
int main()
{
CUT< P> <代码> OB在执行返回后不在范围内。考虑“代码> OB<代码>涉及到返回表达式的评估,它将在返回之前超出范围。 <代码> OB>代码>在范围结束之前,即在<代码> }内不会超出范围。
发生在return
语句之后。此时会调用析构函数,但此时已对i
求值,因此将返回其旧值。局部变量超出范围,并在函数返回后执行其析构函数。这意味着当~A()
运行时,返回值已经是3
。相反,如果你这样做
int foo()
{
{
i=3;
A ob;
}
return i;
}
…ob
将超出范围并在返回语句之前终止,结果将是10
额外作用域通常以这种方式与RAII活动类型(如作用域锁定
)一起使用,以便仅对函数的一部分进入某种特定的副作用状态。当ob
超出作用域时,调用~a()
。
int foo()
{
i=3;
A ob;
return i;
} // <- ~A() is called here
装配证明:
<__Z3foov>:
push %ebp
mov %esp,%ebp
push %ebx
sub $0x10,%esp
movl $0x3,0x407020 /* <-- setting i to 3 */
mov 0x407020,%ebx /* <-- loading i to %ebx */
lea -0x5(%ebp),%eax
mov %eax,%ecx
call 403860 <__ZN1AD1Ev> /* <-- calling destructor */
mov %ebx,%eax /* <-- returnign already calculated i from %ebx */
add $0x10,%esp
pop %ebx
pop %ebp
ret
<__ZN1AD1Ev>: /* <-- the destructor */
push %ebp
mov %esp,%ebp
sub $0x4,%esp
mov %ecx,-0x4(%ebp)
movl $0xa,0x407020 /* <-- set i to 10 */
leave
ret
:
推送%ebp
移动%esp,%ebp
推%ebx
低于$0x10,%esp
MOVL$0x3.0x407020/* <代码> } /代码>括号在C++中生成大量代码:)HASPASACT从不信任一个“结束块”关键字本身是图灵完成的语言。
<__Z3foov>:
push %ebp
mov %esp,%ebp
push %ebx
sub $0x10,%esp
movl $0x3,0x407020 /* <-- setting i to 3 */
mov 0x407020,%ebx /* <-- loading i to %ebx */
lea -0x5(%ebp),%eax
mov %eax,%ecx
call 403860 <__ZN1AD1Ev> /* <-- calling destructor */
mov %ebx,%eax /* <-- returnign already calculated i from %ebx */
add $0x10,%esp
pop %ebx
pop %ebp
ret
<__ZN1AD1Ev>: /* <-- the destructor */
push %ebp
mov %esp,%ebp
sub $0x4,%esp
mov %ecx,-0x4(%ebp)
movl $0xa,0x407020 /* <-- set i to 10 */
leave
ret