C ++ нежелательное уничтожение - PullRequest
2 голосов
/ 19 января 2011

Может кто-нибудь объяснить, почему, когда 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 ]

2 голосов
/ 19 января 2011

В конструкторе C у вас есть

    b = B();

, что это делает:

  • создает временный объект типа B
  • назначает этот объект bс помощью оператора присваивания по умолчанию
  • уничтожить временный объект

Чтобы исправить это, используйте список инициализации в конструкторе C следующим образом:

    C() : b()
    { }

илипросто оставьте конструктор пустым, тогда он будет использовать конструктор по умолчанию.

2 голосов
/ 19 января 2011

Я думаю, что вы хотите объявить c следующим образом:

C c;

Это создаст объект с именем c, который будет уничтожен при выходе из области видимости.С другой стороны, то, что у вас есть;

C c = C();

создаст анонимный объект типа C, скопирует с ним конструкцию c и немедленно уничтожит анонимный объект.С все еще будет уничтожен в конце области.

2 голосов
/ 19 января 2011

В b = B() вы создаете новый временный экземпляр класса B, присваиваете копию b, затем временный экземпляр удаляется.

2 голосов
/ 19 января 2011

Поскольку в конструкторе C вы создаете временный объект B в строке c = B();, и когда назначение завершено, этот временный объект уничтожается.

1 голос
/ 19 января 2011

Вы совершили здесь смертный грех - не подчиняясь правилу 3 .

Ваш B нуждается в деструкторе, но не выполняет копирование и назначение.

Затем вы продолжаете и усугубляете ошибку, фактически выполняя назначение.

Вы также продолжаете удалять неинициализированный указатель. (Было бы хорошо, если бы d было NULL, но нет причины, почему это должно быть).

Вам также необходимо реализовать конструкцию копирования, тем более что ваш компилятор вполне может решить использовать его для вышеуказанных конструкций, хотя, вероятно, на самом деле этого не будет.

1 голос
/ 19 января 2011
Деструктор

временного B называется (b = B();), а не члена b. эта строка может быть вообще удалена, потому что b уже встроено по умолчанию в список неявной инициализации

1 голос
/ 19 января 2011

Строка b = B(); в конструкторе C создает новый объект типа B и использует конструктор копирования B для копирования такого объекта в C::b.

Когда конструктор C возвращает b, он не уничтожается, но временный объект B, используемый для вызова конструктора копирования b, имеет вид.

Вы можете просто удалить такую ​​инструкцию, чтобы избежать создания временного B, в этом случае b будет создан с использованием конструктора по умолчанию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...