Ссылка на объект класса с динамически выделяемой памятью и деструктором - PullRequest
0 голосов
/ 17 февраля 2020

Предположим, у меня есть три класса:

class A{
};

class B{
   int S;
   A* arr;
   B(int s):S(s){
      arr = new A[S];
   }
   ~B(){
   delete [] arr;    
   }
};

class C{
   B& b;
   C(B& b): b(b){}
};

Должен ли я явно определить деструктор в классе C? Как бы это выглядело?

Ответы [ 2 ]

0 голосов
/ 17 февраля 2020

Нет, вам не нужен деструктор для C, но вам нужен конструктор копирования (а также конструктор перемещения, оператор назначения копирования и оператор перемещения-назначения) для класса B, если Вы хотите правильно реализовать семантику копирования. Как и сейчас, если бы вы сделали копию объекта класса B, вам пришлось бы обращаться к объектам, указывающим на один и тот же массив - при уничтожении объектов вы получите двойное удаление, вызывающее неопределенное поведение.

Вам не нужно использовать необработанный указатель. Вы можете просто использовать std::vector, который будет обрабатывать распределение элементов, а также их уничтожение. Это также означает, что вам не нужно реализовывать какие-либо другие конструкторы или деструктор для B, поскольку std::vector обрабатывает копии и перемещается правильно.

0 голосов
/ 17 февраля 2020

Должен ли я явно определить деструктор в классе C?

Чтобы ответить на этот вопрос, вы должны знать, что делает ваш класс. Является ли целью класса управление выделенной памятью? Тогда да, возможно, вам нужен деструктор. Является ли целью ссылка на объект, управляемый чем-то другим? Тогда зачем тебе деструктор? Если вы не знаете, что должен делать деструктор, то он вам часто не нужен.

Никогда не следует использовать ссылки-владельцы, поэтому у C не должно быть особых причин иметь деструктор, или это должно быть радикально изменено.

Вы также не должны использовать собственные указатели, поэтому класс B также должен быть изменен. Самое простое решение - заменить его на std::vector.

...