При каких обстоятельствах я должен обеспечить, оператор присваивания, скопируйте конструктора и деструктор для моего класса C++? [дубликат]

18
задан DavidRR 6 February 2013 в 14:32
поделиться

9 ответов

Если ваш класс содержит в качестве членов данных только объекты vector/string, вам не нужно их реализовывать. Классы C++ STL (такие как vector, string) имеют свой собственный copy ctor, перегруженный оператор присваивания и деструктор.

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

13
ответ дан 30 November 2019 в 08:15
поделиться

Конструктор копирования по умолчанию скопирует вектор, если он объявлен по значению. Будьте осторожны, если вы сохранили указатели в своем векторе, в таком случае вам необходимо обеспечить определенное поведение для копирования / назначения / уничтожения, чтобы избежать утечек памяти или множественного удаления.

4
ответ дан 30 November 2019 в 08:15
поделиться

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

Владеет ли мой класс какими-либо ресурсами?

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

Может ли кто-нибудь унаследовать от моего класса?

Базовым классам нужен деструктор. Херб Саттер рекомендует сделать их общедоступными и виртуальными (наиболее частый случай) или защищенными и не виртуальными, в зависимости от того, что вы хотите. что с ними делать. Деструктор, созданный компилятором, является общедоступным и не виртуальным, поэтому вам придется написать свой собственный, даже если в нем нет кода. ( Примечание: это не означает, что вам нужно писать конструктор копирования или оператор присваивания. )

Следует ли мне запретить пользователю копировать объекты моего класса?

Если вы не хотите пользователю, чтобы скопировать ваши объекты (может быть, это слишком дорого), вам нужно объявить конструктор копирования и операторы присваивания либо protected , либо private . Их не нужно реализовывать, если они вам не нужны. ( Примечание: это не означает, что вам нужно писать деструктор.)

Итог:

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

3
ответ дан 30 November 2019 в 08:15
поделиться

в этом контейнере потребуется элемент «копируемый конструктор», и если вы не предоставите конструктор копирования, он вызовет конструктор копирования по умолчанию для вашего класса вывод из ваших учеников (мелкая копия).

простое объяснение конструктора копирования по умолчанию находится здесь: http://www.fredosaurus.com/notes-cpp/oop-condestructors/copyconstructors.html

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

1
ответ дан 30 November 2019 в 08:15
поделиться

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

По моему опыту, всегда лучше определить их самостоятельно и выработать привычку следить за тем, чтобы они сохранялись при смене класса. Во-первых, вы можете захотеть поставить точку останова при вызове определенного ctor или dtor. Также отсутствие их определения может привести к раздуванию кода, поскольку компилятор будет генерировать встроенные вызовы членов ctor и dtor (у Скотта Мейерса есть раздел об этом).

Также иногда вы хотите запретить использование заданных по умолчанию операторов копирования и назначений. Например, у меня есть приложение, которое хранит и обрабатывает очень большие блоки данных. У нас обычно есть эквивалент вектора STL, содержащий миллионы трехмерных точек, и было бы катастрофой, если бы мы позволили создавать копии этих контейнеров. Таким образом, операторы ctor и присваивания объявлены частными и не определены.Таким образом, если кто-нибудь напишет

class myClass {
  void doSomething(const bigDataContainer data); // not should be passed by reference
}

, он получит ошибку компилятора. Наш опыт показывает, что явные методы стать () или clone () гораздо менее подвержены ошибкам.

В общем, есть много причин избегать автоматически сгенерированных функций компилятора.

2
ответ дан 30 November 2019 в 08:15
поделиться

Когда у вас есть класс, требующий глубоких копий, вы должны определить их.

В частности, любой класс, содержащий указатели или ссылки, должен содержать их, например:

class foo {
private:
    int a,b;
    bar *c;
}

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

0
ответ дан 30 November 2019 в 08:15
поделиться

Не для строк или векторов, поскольку тривиальные конструкторы / деструкторы и т.д. будут работать нормально.

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

0
ответ дан 30 November 2019 в 08:15
поделиться

Обычное правило гласит: если вам нужен один из них, то вам нужны все.

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

5
ответ дан 30 November 2019 в 08:15
поделиться

вы должны предоставить их, если они вам нужны. или возможные пользователи ваших классов. деструктор всегда должен , а конструкторы копирования и оператор присваивания автоматически создаются компилятором. (По крайней мере, MSVC)

0
ответ дан 30 November 2019 в 08:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: