У меня была структура со многими полями простых типов (UINT, CString, COLORREF и т. Д.). Проект компилировался хорошо.
Затем я добавил a, который добавил CArray в структуру. Это не компилировалось.
Затем я реализовал operator = и скопировал конструктор для этой структуры (один используя другой). Затем он скомпилирован.
Через некоторое время, выполняя обслуживание структуры, я провел эксперимент: изменил CArray на std :: vector, удалил operator = и скопировал конструктор. Он скомпилировался нормально, и структура была хорошо скопирована, где вызывался оператор = или конструктор копирования.
Преимущество состоит в том, что я могу вывести бесполезную часть кода, подверженную ошибкам и, вероятно, не обновленную, когда кто-то делал техническое обслуживание, добавляя поле в структуру! - и я вижу в этом большое преимущество.
ПРИЧИНА:
Почему мне сейчас не нужен конструктор копирования и оператор присваивания =?
Раньше структура имела только поля простого типа. Таким образом, они были копируемыми. Будучи копируемыми, все это делает структуру копируемой. Когда я добавил поле CArray, это поле не было копируемым, потому что CArray наследуется от CObject, класса, который явно делает эти две функции закрытыми:
class AFX_NOVTABLE CObject
{
//...
private:
CObject(const CObject& objectSrc); // no implementation
void operator=(const CObject& objectSrc); // no implementation
//...
}
А CArray, являющийся классом, производным от CObject, не предпринимает никаких действий, чтобы переопределить это поведение, поэтому CArray унаследует его и сделает себя недоступным для копирования. Добавив CArray перед копированием структуры, я получил ошибку:
c:\program files\microsoft visual studio 8\vc\atlmfc\include\afxtempl.h(272) : error C2248: 'CObject::operator =' : cannot access private member declared in class 'CObject'
c:\program files\microsoft visual studio 8\vc\atlmfc\include\afx.h(554) : see declaration of 'CObject::operator ='
c:\program files\microsoft visual studio 8\vc\atlmfc\include\afx.h(524) : see declaration of 'CObject'
This diagnostic occurred in the compiler generated function 'CArray<TYPE,ARG_TYPE> &CArray<TYPE,ARG_TYPE>::operator =(const CArray<TYPE,ARG_TYPE> &)'
with
[
TYPE=unsigned int,
ARG_TYPE=unsigned int &
]
std :: vector копируется по собственному определению:
// TEMPLATE CLASS vector
template<class _Ty,
class _Ax = allocator<_Ty> >
class vector
: public _Vector_val<_Ty, _Ax>
{ // varying size array of values
public:
typedef vector<_Ty, _Ax> _Myt;
Обратите внимание: _Myt является typedef для самого векторного класса.
//...
vector(const _Myt& _Right)
: _Mybase(_Right._Alval)
{ // construct by copying _Right
if (_Buy(_Right.size()))
_TRY_BEGIN
this->_Mylast = _Ucopy(_Right.begin(), _Right.end(),
this->_Myfirst);
_CATCH_ALL
_Tidy();
_RERAISE;
_CATCH_END
}
//...
vector(_Myt&& _Right)
: _Mybase(_Right._Alval)
{ // construct by moving _Right
_Assign_rv(_STD forward<_Myt>(_Right));
}
_Myt& operator=(_Myt&& _Right)
{ // assign by moving _Right
_Assign_rv(_STD forward<_Myt>(_Right));
return (*this);
}
//...
}
Итак, добавление поля члена std :: vector в struct / class не потребует от вас реализации функций копирования внутри него, только из-за этого нового поля.