Конструкторы копирования и перемещения :: Cетевой уголок Majestio

Конструкторы копирования и перемещения


Типа на заметку для С++11 и выше:

class MyClass {
  MyClass (const MyClass &Tmp);               // Конструктор копирования (медленный)
  MyClass (MyClass &&Tmp);                    // Конструктор переноса из временного объекта (быстрый)
  MyClass & operator = (const MyClass &Tmp);  // Обычное присваивание (медленное)
  MyClass & operator = (MyClass &&Tmp);       // Перенос временного объекта (быстрый)
};

Пример из Хабра:

#include <iostream>
#include <memory>
#include <cassert>
 
using namespace std;
 
template <typename T>
class Buffer {
 
    std::string          Name;
    size_t               Size;
    std::unique_ptr<T[]> Buff;
 
  public:
 
    // Конструктор по умолчанию
    Buffer():
      Size(16),
      Buff(new T[16]) {
    }
 
    // Конструктор
    Buffer(const std::string& iName, size_t iSize):
      Name(iName),
      Size(iSize),
      Buff(new T[iSize])
    {}
 
    // Конструктор копирования
    Buffer(const Buffer& iCopy):
      Name(iCopy.Name),
      Size(iCopy.Size),
      Buff(new T[iCopy.Size]) {
      T* source = iCopy.Buff.get();
      T* dest = Buff.get();
      std::copy(source, source + iCopy.Size, dest);
    }
 
    // Оператор присваивания
    Buffer& operator=(const Buffer& iCopy) {
      if (this != &iCopy) {
        Name = iCopy.Name;
        if (Size != iCopy.Size) {
          Buff = nullptr;
          Size = iCopy.Size;
          Buff = (Size > 0)? new T[Size] : nullptr;
        }
        T* source = iCopy.Buff.get();
        T* dest = Buff.get();
        std::copy(source, source + iCopy.Size, dest);
      }
      return *this;
    }
 
    // Конструктор переноса
    Buffer(Buffer&& iTemp):
      Name(std::move(iTemp.Name)),
      Size(iTemp.Size),
      Buff(std::move(iTemp.Buff)) {
      iTemp.Buff = nullptr;
      iTemp.Size = 0;
    }
 
    // Оператор пререноса
    Buffer& operator=(Buffer&& iTemp) {
      assert(this != &iTemp); // уведомление если объект не временный
      Buff = nullptr;
      Size = iTemp.Size;
      Buff = std::move(iTemp.Buff);
      Name = std::move(iTemp.Name);
      iTemp.Buff = nullptr;
      iTemp.Size = 0;
      return *this;
    }
};
 
template <typename T>
Buffer<T> GetBuffer(const std::string& iName) {
  Buffer<T> B(iName, 128);
  return B;
}
 
int main() {
  Buffer<int> B1;
  Buffer<int> B2("Buf2", 64);
  Buffer<int> B3 = B2;
  Buffer<int> B4 = GetBuffer<int>("Buf4");
  B1 = GetBuffer<int>("Buf5");
  return 0;
}
Рейтинг: 0/5 - 0 голосов