Comments 12
Вы не совсем правы. Компилятор не удаляет просто так конструкторы копирования, а может удалить только пару констуктор копирования-деструктор. Так что, если ваши конструктор копирования и деструктор не имеют побочных эффектов (а с чего бы им?), а деструктор просто «отменяет» действие конструктора копирования то ничего страшного и достойного громкой статьи с подзаголовком «Страшная правда» тут нет.
По идее, retain/release пара должна обладать именно такой семантикой, и на первый взгляд непонятно, как у вас получилось сделать иначе.
По идее, retain/release пара должна обладать именно такой семантикой, и на первый взгляд непонятно, как у вас получилось сделать иначе.
+10
Да, вы совершенно правы. Я провёл дополнительные тесты — статья требует серьёзных уточнений… Постараюсь внести правки как можно скорее.
По поводу уточнённой проблемы задавал ещё вопрос на stack overflow. Там люди дали достаточно хороший ответ.
По поводу уточнённой проблемы задавал ещё вопрос на stack overflow. Там люди дали достаточно хороший ответ.
0
del
0
А почему у вас ожидаемый результат
? Два раза Destroy же должен случиться, 1 раз для временного объекта после Const Copy, и уничтожить тот, который первым написал Default, а второй раз в конце. Вот этот второй деструктор и схлопнулся с копирующим конструктором. В таких дебажных строках очень полезно печатать значение this.
Кстати, в gcc есть ещё похожая оптимизация, связанная с возвращаемым из функции значением.
Default
Const Copy
Call 1
Destroy
? Два раза Destroy же должен случиться, 1 раз для временного объекта после Const Copy, и уничтожить тот, который первым написал Default, а второй раз в конце. Вот этот второй деструктор и схлопнулся с копирующим конструктором. В таких дебажных строках очень полезно печатать значение this.
Кстати, в gcc есть ещё похожая оптимизация, связанная с возвращаемым из функции значением.
+3
Кстати, в gcc есть ещё похожая оптимизация, связанная с возвращаемым из функции значением.Вы про Return Value Optimization (RVO)? Согласно Вики, эта оптимизация не только в gcc есть, но и в большинстве других компиляторов.
0
В случае, если выставить это слово перед copy-конструктором, мы получим достаточно забавный запрет неявного приведения типа — запрет приведения к своему типу.
Что ещё забавнее, из-за особенностей синтаксиса С++ вот так: TestClass theTestObject(TestClass()) записать тоже не выйдет, ведь это будет считаться объявлением указателя на функцию и вызовет ошибку:
Мне кажется, у вас есть некоторая путаница с пониманием видов инициализации в C++ (в данном случае direct и copy, инициализация через = в объявлении ведет к copy).
А на счет невозможности написать из-за особенностей синтаксиса — применяйте uniform-инициализацию (TestClass{}), ваш компилятор должен поддерживать такой синтаксис.
+2
template<typename T_OtherType,
typename T_OtherHolding,
typename T_OtherAccess>
DReference(
const DReference<T_OtherType, T_OtherHolding, T_OtherAccess> &
inLReference) : _holder(NULL), _holding(), _access()
{
retain(inLReference._holder);
}
Это единственный конструктор, предназначеный для копирования DReference?
0
Для корректной работы умных указателей вам необходимо определить DReference& DReference::operator = (const DReference&), либо удалить его реализацию по-умолчанию — не знаю, сделали вы это или нет. Реализация по-умолчанию в вашем случае приводит к ошибкам.
EDIT: ошибся с веткой немного
EDIT: ошибся с веткой немного
0
Да, когда я писал статью был единственным. Но буквально через несколько дней после отправки на премодерацию я понял как сильно сглупил, добавил его — и одной ошибкой стало меньше.
0
Перечитал статью внимательнее. Судя по симптомам и лечению, действительно (был) единственный.
ISO IEC 14882-2003 §12.8 Copying class objects [class.copy]
Сноска:
ISO IEC 14882-2011 §12.8 Copying class objects [class.copy]
Т.е. шаблонный конструктор не считается за конструктор копирования как бы вы его не шаблонили, поэтому компилятор сделал свой и использует его когда он лучше подходит, чем шаблонный.
Т.е. нужно явно определять конструктор копирования, что вы в итоге и сделали, но это не «some magic cases», а так и задумано.
А copy-elision тут ни в чём не виновен.
ISO IEC 14882-2003 §12.8 Copying class objects [class.copy]
A member function template is never instantiated to perform the copy of a class object to an object of its class type.
Сноска:
106) Because a template constructor is never a copy constructor, the presence of such a template does not suppress the implicit declaration of a copy constructor. Template constructors participate in overload resolution with other constructors, including copy constructors, and a template constructor may be used to copy an object if it provides a better match than other constructors.
ISO IEC 14882-2011 §12.8 Copying class objects [class.copy]
A member function template is never instantiated to produce such a constructor signature.
Т.е. шаблонный конструктор не считается за конструктор копирования как бы вы его не шаблонили, поэтому компилятор сделал свой и использует его когда он лучше подходит, чем шаблонный.
Т.е. нужно явно определять конструктор копирования, что вы в итоге и сделали, но это не «some magic cases», а так и задумано.
А copy-elision тут ни в чём не виновен.
+4
Sign up to leave a comment.
(Без)опасный copy elision