Конструктор копирования по умолчанию является член за элементом, а не поразрядным.
Большинство производных от CObject классов содержат - и управляют напрямую - некоторыми системными ресурсами, у которых нет подсчета ссылок или аналогичного механизма, поэтому выбор, вероятно, был сделан с учетом варианта использования по умолчанию.
например. CGDIObject - это примерно:
class CGDIObject : public CObject
{
HGDIOBJ m_handle;
CGDIObject() : m_handle(0) {}
// derived classes provide a create, attach etc.
~CGDIObject() { DeleteObject(m_handle); }
}
Конструктор копирования по умолчанию здесь был бы опасен (приводил к двойному уничтожению), поэтому обеспечение «правильного» конструктора копирования на удивление сложно и дорого.
Другая причина может заключаться в том, что большинство производных от CObject классов предназначены для мутации и, следовательно, для передачи по ссылке. Отсутствующий конструктор копии будет перехватывать непреднамеренные копии, которые изменяют копию, а не переданный объект:
class CMyObject : public CObject
{
public:
AttachFoo(FooHandle foo) { ... }
AddBar() { ... }
};
bool InitMySession(CMyObject & obj)
{
obj.AttachFoo(CreateRawFoo());
obj.AddBar();
obj.AddBar();
}
// ...
CMyObj mo;
InitMySession(mo);
Пропуск "&" дает вам код, который хорошо компилируется, но создает временную копию, изменяет ее, а затем удаляет ее, в то время как mo
остается неизменной.
Довольно много API следуют этому шаблону, поскольку MFC не полагается на исключения для обработки ошибок (по историческим причинам: не все целевые компиляторы хорошо их поддерживали, и MFC требует много дополнительной обработки ресурсов, которая становится болезненной из-за исключений) ,
Я не думаю, что этот выбор хорош, например, производные классы должны иметь возможность использовать конструктор копирования по умолчанию, если их члены разрешают (и большинство членов должны разрешать).
Решение соответствует «образу мышления» МФЦ и требованиям / ограничениям времени создания МФЦ.