构造函数和析构函数如何工作?
How the constructor and destructor work?
class Foo{
public:
Foo(){
cout <<"C ";
}
~Foo(){
cout <<"D ";
}
};
void func(){
Foo* p = new Foo;
p = NULL;
}
int main(){
Foo a;
for (int i=0; i<1; i++){
Foo b;
if (true){
Foo c;
}
func();
}
return 0;
}
这道题的输出是C C C D C D D,如果我把main函数中的func()去掉,输出就变成了C C C D D D,前3个C我看懂了,但是我不明白后面的剩下的请解释一下,谢谢
- C-a构造
- C-b构造
- C - c构造
- D - c 被破坏因为你离开了作用域
- C - 一个对象 Foo 被动态分配并由 p 指向,但由于它是动态分配的,并且从未被删除,因此它永远不会被破坏。
- D - b 被破坏
- D - a 被破坏
C C C D C D D 的顺序是:
- C - 构造 A
- C - 构造 B
- C - 构造 C
- D - 破坏 C
- C - 构造 p(在 func 中)
- D - 摧毁 B
- D - 摧毁 A
// p 的内存泄漏(在 func 中)
包含func();
调用时,采取的步骤是:
Foo a; -> C
Foo b; -> C
Foo c; -> C
Left the scope of Foo c -> D
func(); call ->
new Foo; -> C
Finished func() call, left the scope of Foo b -> D
Left the scope of Foo a -> D
请注意,在 func() 中创建的 Foo 对象永远不会被解构,这意味着您有内存泄漏。
对象的作用域a
是main函数外层代码块的作用域。它是创建的第一个对象和删除的最后一个对象。
int main(){
Foo a;
// ...
return 0;
}
C C C D C D D
| |
a a
然后在只有一次迭代的 for 循环中创建对象 b
,在循环的第一次迭代后删除
for (int i=0; i<1; i++){
Foo b;
// ...
}
C C C D C D D
| | | |
a b b a
然后在语句块范围内if
if (true){
Foo c;
}
创建和删除对象c
C C C D C D D
| | | | | |
a b c c b a
之后函数func
被调用
func();
在函数内部,使用 operator new 创建了一个未命名的对象,并由指针 p
.
指向
void func(){
Foo* p = new Foo;
p = NULL;
}
C C C D C D D
| | | | | | |
a b c c p b a
这个对象没有被删除,因为没有为这个对象调用删除运算符。所以存在内存泄漏。
就是这样。
class Foo{
public:
Foo(){
cout <<"C ";
}
~Foo(){
cout <<"D ";
}
};
void func(){
Foo* p = new Foo;
p = NULL;
}
int main(){
Foo a;
for (int i=0; i<1; i++){
Foo b;
if (true){
Foo c;
}
func();
}
return 0;
}
这道题的输出是C C C D C D D,如果我把main函数中的func()去掉,输出就变成了C C C D D D,前3个C我看懂了,但是我不明白后面的剩下的请解释一下,谢谢
- C-a构造
- C-b构造
- C - c构造
- D - c 被破坏因为你离开了作用域
- C - 一个对象 Foo 被动态分配并由 p 指向,但由于它是动态分配的,并且从未被删除,因此它永远不会被破坏。
- D - b 被破坏
- D - a 被破坏
C C C D C D D 的顺序是:
- C - 构造 A
- C - 构造 B
- C - 构造 C
- D - 破坏 C
- C - 构造 p(在 func 中)
- D - 摧毁 B
- D - 摧毁 A
// p 的内存泄漏(在 func 中)
包含func();
调用时,采取的步骤是:
Foo a; -> C
Foo b; -> C
Foo c; -> C
Left the scope of Foo c -> D
func(); call ->
new Foo; -> C
Finished func() call, left the scope of Foo b -> D
Left the scope of Foo a -> D
请注意,在 func() 中创建的 Foo 对象永远不会被解构,这意味着您有内存泄漏。
对象的作用域a
是main函数外层代码块的作用域。它是创建的第一个对象和删除的最后一个对象。
int main(){
Foo a;
// ...
return 0;
}
C C C D C D D
| |
a a
然后在只有一次迭代的 for 循环中创建对象 b
,在循环的第一次迭代后删除
for (int i=0; i<1; i++){
Foo b;
// ...
}
C C C D C D D
| | | |
a b b a
然后在语句块范围内if
if (true){
Foo c;
}
创建和删除对象c
C C C D C D D
| | | | | |
a b c c b a
之后函数func
被调用
func();
在函数内部,使用 operator new 创建了一个未命名的对象,并由指针 p
.
void func(){
Foo* p = new Foo;
p = NULL;
}
C C C D C D D
| | | | | | |
a b c c p b a
这个对象没有被删除,因为没有为这个对象调用删除运算符。所以存在内存泄漏。
就是这样。