Подтвердить что ты не робот

Почему пользовательский движок-конструктор отключает неявный конструктор-копию?

Пока я читаю boost/shared_ptr.hpp, я видел этот код:

//  generated copy constructor, destructor are fine...

#if defined( BOOST_HAS_RVALUE_REFS )

// ... except in C++0x, move disables the implicit copy

shared_ptr( shared_ptr const & r ): px( r.px ), pn( r.pn ) // never throws
{
}

#endif

Что такое созданный конструктор копии, деструктор, отлично, за исключением С++ 11, перемещение отключает неявную копию "означает здесь? Должны ли мы всегда писать копию ctor сами, чтобы предотвратить эту ситуацию в С++ 11?

4b9b3361

Ответ 1

Я поддержал ответ ildjarn, потому что нашел его как точным, так и юмористическим.: -)

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

фон

С++ имеет неявно сгенерированные экземпляры копии, потому что, если бы это не так, это было бы все еще родиться в 1985 году, потому что это было , поэтому несовместимо с C. И в этом случае мы не были бы сегодня этот разговор, потому что С++ не существует.

При этом неявно сгенерированные экземпляры копий сродни "сделке с дьяволом". С++ не мог родиться без них. Но они злы в том, что они молча порождают неправильный код в значительном числе случаев. Комитет С++ не глуп, они это знают.

С++ 11

Теперь, когда С++ родился и превратился в успешный взрослый, комитет просто хотел бы сказать: мы больше не делаем неявно сгенерированных членов экземпляра. Они слишком опасны. Если вам нужен неявно сгенерированный член копии, вы должны отказаться от этого решения (в отличие от отказа от него). Однако, учитывая количество существующего кода на С++, который сломался бы, если бы это было сделано, это было бы равносильно самоубийству. Существует огромная проблема обратной совместимости, которая вполне оправдана.

Таким образом, комитет достиг компромиссной позиции: если вы объявляете участников движения (что не может сделать код на языке С++), мы предположим, что члены экземпляра по умолчанию, вероятно, сделают неправильную вещь. Выбирайте (с =default), если хотите. Или напишите их сами. В противном случае они неявно удаляются. Наш опыт на сегодняшний день в мире с типами только для перемещения указывает на то, что это положение по умолчанию на самом деле обычно является желательным (например, unique_ptr, ofstream, future и т.д.). И расход на выбор фактически невелик с = default.

В ожидании

Комитет хотел бы даже сказать: если вы написали деструктор, вполне вероятно, что члены неявной копии неверны, поэтому мы удалим их. Это правило С++ 98/03 из трех. Однако даже это сломало бы много кода. Однако комитет сказал в С++ 11, что если вы предоставите объявленный пользователем деструктор, неявное генерирование членов экземпляра устарело. Это означает, что эта функция может быть удалена в будущем стандарте. И что в любой момент ваш компилятор может начать выдавать "устаревшие предупреждения" в этой ситуации (стандарт не может указывать предупреждения).

Заключение

Так что будьте предупреждены: С++ вырос и созрела на протяжении десятилетий. А это означает, что вашему отцу С++ может потребоваться переход на работу с вашим ребенком С++. Это медленный, постепенный процесс, чтобы вы не поднимали руки и не переносили на другой язык. Но это есть, даже если оно медленное.

Ответ 2

Потому что стандарт С++ говорит так: ndash; §12.8/7:

Если определение класса явно не объявляет конструктор копирования, он объявляется неявно. Если определение класса объявляет конструктор перемещения или переносит оператор присваивания, неявно объявленный конструктор копирования определяется как удаленный; в противном случае он определяется как дефолт. Последний случай устарел, если класс имеет пользовательский оператор присваивания копии или объявленный пользователем деструктор. Таким образом, для определения класса

struct X {
    X(const X&, int);
};

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

X::X(const X& x, int i =0) { /* ... */ }

то любое использование конструктора Xs copy плохо сформировано из-за двусмысленности; диагностика не требуется.

(Подчеркните мой.)