Почему отключают конструктора и присвоение копии COBJECT

Конструктор и присвоение копии CObject's корневого объекта MFC отключены по умолчанию.

Типичный конструктор копии класса значения по умолчанию C++ делает копию участника участником. Присутствие частного CObject копирует гарантии конструктора сообщение ошибки компилятора, если конструктор копии Вашего класса необходим, но не доступный. Необходимо поэтому предоставить конструктору копии, если класс требует этой возможности.

  • В исходном коде COBJECT существует комментарий:

Отключите конструктора копии и присвоение по умолчанию, таким образом, Вы получите ошибки компилятора вместо неожиданного поведения, если Вы передадите объекты значением или присвоите объекты.

Мой вопрос, какова проблема со значением по умолчанию, поразрядно копируют конструктора для этого класса CObject? По-моему, было бы лучше дать нам конструктора копии по умолчанию, и мы могли обеспечить тот при необходимости (глубокая копия)

8
задан Baiyan Huang 22 June 2010 в 00:20
поделиться

2 ответа

Конструктор копирования по умолчанию является поэлементным, а не побитовым.

Большинство классов, производных от 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 требует много дополнительных операций с ресурсами, что становится болезненным из-за исключений) .


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

Однако это решение соответствует «образу мышления» MFC и требованиям / ограничениям времени создания MFC.

6
ответ дан 5 December 2019 в 18:56
поделиться

Примите во внимание следующее:

class CMyHandle : public CObject
{
    HANDLE hWin32;
public:
    CMyHandle()
    {
        hWin32 = SomeFunctionThatMakesHandle();
    }
    ~CMyHandle()
    {
        CloseHandle(hWin32);
    }
};

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

Поскольку большое количество классов MFC управляет дескрипторами, имеет смысл заставить создателя класса явно переопределить создание конструкторов копирования и операторов присваивания копий.

РЕДАКТИРОВАТЬ: Например:

int main()
{
    CMyHandle h1; //CMyHandle's constructor initializes the handle
    {
        CMyHandle h2(h1); //Memberwise copy into h2. In this case, it copies the
                          //handle
    } //h2 destroyed, closes handle
    //h1 is now invalid (because the underlying handle was closed)!
}
3
ответ дан 5 December 2019 в 18:56
поделиться
Другие вопросы по тегам:

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