C ++不需要的破坏

时间:2011-01-19 13:52:31

标签: c++ oop constructor destructor

有人可以解释为什么当c完成构建时,b(c成员)的析构函数被调用,而d被解析 - 正如预期的那样 - c析构函数被称为?

#include <iostream>

using namespace std;

class A
{
public:
    int a, b;
};

class B
{
public:
    A* array[10];
    B()
    {
        for(int i = 0 ; i < 10 ; i++)
            array[i] = new A();
    }
    ~B()
    {
        for(int i = 0 ; i < 10 ; i++)
            delete array[i];
    }
};

class C
{
public:
    B b;
    B* d;
    C()
    {
        b = B();
    }
    ~C()
    {
            delete d;
    }
};

int main()
{
    B b = B();
    C c = C();
    cout << "Ashlamish" << endl;
    system("pause");
    return 0;
}

7 个答案:

答案 0 :(得分:2)

因为在C的构造函数中,您在行c = B();中创建了一个临时B对象,当赋值完成时,该临时对象正在被销毁。

答案 1 :(得分:2)

b = B()中,您正在构建一个新的B类临时实例,为b分配一个副本,然后对该临时实例进行解析。

答案 2 :(得分:2)

我想你想宣布这样的:

C c;

这将构造一个名为c的对象,它将在作用域出口处被破坏。 另一方面,你有什么;

C c = C();

将构造一个C类型的匿名对象,使用它复制构造c并立即销毁匿名对象。 c将在范围的最后被破坏。

答案 3 :(得分:2)

在C的构造函数中,你有

    b = B();

这是做什么的:

  • 构造B类临时对象
  • 使用默认分配运算符
  • 将此对象分配给b
  • 销毁临时对象

要在C的构造函数中修复此使用初始化列表,如下所示:

    C() : b()
    { }

或者只是将构造函数留空,这样它将使用默认构造函数。

答案 4 :(得分:1)

b = B();构造函数中的行C实例化B类型的新对象,并使用B的复制构造函数在C::b中复制此类对象

C构造函数返回b时不会被销毁,但用于调用B的复制构造函数的b临时对象是。

你可以删除这样的指令,以避免实例化B临时,在这种情况下,b将只使用默认构造函数构建。

答案 5 :(得分:1)

临时B的析构函数称为(b = B();),而不是成员b。可以删除此行,因为b已经在隐式初始化列表

中默认构造

答案 6 :(得分:1)

你在这里犯了一个重大的罪 - 不遵守rule of 3

你的B需要一个析构函数,但不实现复制和赋值。

然后继续通过实际执行任务来加剧错误。

您还会继续删除未初始化的指针。 (如果d为NULL,那就没关系了,但没有理由这样做。)

您还需要实现复制构造,尤其是您的编译器可能会选择将其用于上述构造,尽管它可能实际上不会这样做。