Почему деструктор C ++ по умолчанию не уничтожает мои объекты? - PullRequest
28 голосов
/ 08 марта 2010

В спецификации C ++ говорится, что деструктор по умолчанию удаляет все нестатические элементы. Тем не менее, мне не удается этого добиться.

У меня есть это:

class N {
public:
    ~N() {
        std::cout << "Destroying object of type N";
    }
};

class M {
public:
    M() {
        n = new N;
    }
//  ~M() { //this should happen by default
//      delete n;
//  }
private:
    N* n;
};

Тогда это должно напечатать данное сообщение, но это не так:

M* m = new M();
delete m; //this should invoke the default destructor

Ответы [ 13 ]

1 голос
/ 08 марта 2010

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

int main(int argc, char* argv[])
{
  N* n = new N();
} // n is destructed here

Это тоже ничего не печатает.

Почему? Поскольку pointer (n) разрушен, а не объект, указанный на *n.

Конечно, вы не захотите, чтобы он уничтожил объект, на который указывает:

int main(int argc, char* argv[])
{
  N myObject;
  {
    N* n = &myObject;
  } // n is destructed here, myObject is not

  myObject.foo();
} // myObject is destructed here

Вы должны помнить, что в отличие от языков, таких как C# или Java, существует два способа создания объектов в C ++: непосредственно N myObject (в стеке) или через new, как в new N(), в этом случае объект помещается в кучу, и вы несете ответственность за его освобождение в более позднее время.

Итак, ваш деструктор уничтожает указатель, но не объект, на который указывает. Выделите объект без нового (и без использования указателя) или используйте Smart Pointer, если вы хотите, чтобы он был автоматическим.

1 голос
/ 08 марта 2010

Старайтесь избегать использования указателей. Они являются последним средством.

class N {
public:
    ~N() {
        std::cout << "Destroying object of type N";
    }
};

class M {
public:
    M() {
       // n = new N; no need, default constructor by default
    }
//  ~M() { //this should happen by default
//      delete n;
//  }
private:
    N n; // No pointer here
};

Тогда используйте это так

main(int, char**)
{
    M m;
}

Появится Уничтожающий объект типа N

.
0 голосов
/ 25 декабря 2014
class N {
public:
    ~N() {
        std::cout << "Destroying object of type N";
    }
};

class M {
public:
    M() {
        n = new N;
    }
//  ~M() { //this should happen by default
//      delete n;
//  }
private:
    N* n;
};

и теперь ожидание:

M* m = new M();
delete m; //this should invoke the default destructor

Это произойдет, только если класс M получен из N:

class M: Class N {
...

Только в этой ситуации,

M* m = new M()

вызовет конструктор N, а затем конструктор M, где

delete m;

сначала автоматически вызовет деструктор M, а затем N

...