构造函数和析构函数如何工作?

时间:2017-05-19 19:11:20

标签: c++ constructor destructor

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;
}

对于这个问题,输出是CCCDCDD,如果我删除main函数中的func(),输出变为CCCDDD,我理解它来自的第一个3 C,但我不明白剩下的,请解释一下,谢谢。

4 个答案:

答案 0 :(得分:2)

  1. C - a构建
  2. 构建C - b
  3. 构建C - c
  4. D-c因为你离开范围而被解除了
  5. C - 一个对象Foo是由p动态分配和指向的,但由于它是动态分配的,而且从不删除,所以它永远不会被破坏。
  6. D - b被破坏
  7. D - a被毁坏

答案 1 :(得分:2)

对象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 (true){
        Foo c;
    }

创建并删除了对象c

C C C D C D D
| | | |   | |
a b c c   b a

之后调用函数func

func();

在函数内部,使用new运算符创建了一个未命名的对象,并由指针p指向。

void func(){
    Foo* p = new Foo;
    p = NULL;
}

C C C D C D D
| | | | | | |
a b c c p b a

不会删除此对象,因为不会为此对象调用operator delete。所以存在内存泄漏。

就是这样。

答案 2 :(得分:1)

顺序是C C C D C D D:

  1. C - 构造A
  2. C - 构造B
  3. C - 构造C
  4. D - Destruct C
  5. C - 构造p(在func中)
  6. D - Destruct B
  7. D - Destruct A
  8. // memleak for p(in func)

答案 3 :(得分:0)

当包含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对象永远不会被破坏,这意味着您有内存泄漏。