Занимательная задачка: понимание deep copy

Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain

Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

А вот вариант на сырых поинтерах, чтобы явно показать, как должен работать move-конструктор:

Код: Выделить всё

/* testing data section begin */

class CHuge
{
public:
   void DoAction(){}
};

constexpr bool g_bSomeCondition1 = true;
constexpr bool g_bSomeCondition2 = true;
constexpr bool g_bSomeCondition3 = true;

/* testing data section end */

class CWorker
{
public:
   CWorker() : m_pHuge(nullptr)
   { }

   CWorker(const CWorker& rhs) : m_pHuge(nullptr)
   {
      if (rhs.m_pHuge)
      {
          m_pHuge = new CHuge(*rhs.m_pHuge);
      }
   }

   CWorker(CWorker&& rhs) : m_pHuge(rhs.m_pHuge)
   {
      rhs.m_pHuge = nullptr;
   }

   CWorker& operator=(const CWorker& rhs)
   {
      if (this != &rhs)
      {
         if (m_pHuge)
         {
            delete m_pHuge;
            m_pHuge = nullptr;
         }
         if (rhs.m_pHuge)
         {
             m_pHuge = new CHuge(*rhs.m_pHuge);
         }
      }
      return *this;
   }

   ~CWorker()
   {
      delete m_pHuge;
   }

   void Process()
   {
      if (!m_pHuge)
      {
         m_pHuge = new CHuge;
      }
      m_pHuge->DoAction();
   }

private:
   CHuge* m_pHuge;
};

int main()
{
   CWorker worker1;
   if (g_bSomeCondition1)
   {
      worker1.Process();
   }

   CWorker worker2;
   if (g_bSomeCondition2)
   {
      worker2 = worker1;
   }

   if (g_bSomeCondition3)
   {
      worker1.Process();      
      worker2.Process();
   }

   return 0;
}
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Аватара пользователя
Din666
Сообщения: 52
Зарегистрирован: 17 июл 2015, 13:25
Откуда: Moscow
Контактная информация:

Чайниковский Вопрос: А как понять когда вызывается Мув конструктор?
Absurd
Сообщения: 1228
Зарегистрирован: 26 фев 2004, 13:24
Откуда: Pietari, Venäjä
Контактная информация:

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

Код: Выделить всё

foo(std::string("Baz"));
Здесь функции foo передается временный std::string. Если у foo есть перегрузка принимающая std::string&&, то будет использована именно она. Так же можно превратить объект во временный при помощи std::move или std::forward.
2B OR NOT(2B) = FF
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Да, вызывается, когда справа стоит временный объект. То есть либо безымянный, либо созданный для преобразования (как в примере Absurd'a), либо результат возврата функции по значению.

Так же можно явно инициировать мувинг, воспользовавшись функцией std::move.

Код: Выделить всё

#include <string>

std::string str1 = "Hello";
std::string str2(std::move(str1));
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Аватара пользователя
Din666
Сообщения: 52
Зарегистрирован: 17 июл 2015, 13:25
Откуда: Moscow
Контактная информация:

Большое Спасибо, надо будет почитать повнимательнее про новый стандарт.
Ответить