Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
Разработка программного обеспечения

Implementing copyable and movable classes

Boost , The Boost C++ Libraries BoostBook Documentation Subset , Chapter 23. Boost.Move

Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

PrevUpHomeNext

Рассмотрим простой класс рукояток, который владеет ресурсом, а также предоставляет копировальную семантику (копический конструктор и присвоение). Например, clone_ptr может владеть указателем и вызывать clone() на нем для копирования целей:

template <class T>
class clone_ptr
{
   private:
   T* ptr;
   public:
   // construction
   explicit clone_ptr(T* p = 0) : ptr(p) {}
   // destruction
   ~clone_ptr() { delete ptr; }
   // copy semantics
   clone_ptr(const clone_ptr& p)
      : ptr(p.ptr ? p.ptr->clone() : 0) {}
   clone_ptr& operator=(const clone_ptr& p)
   {
      if (this != &p)
      {
         T *p = p.ptr ? p.ptr->clone() : 0;
         delete ptr;
         ptr = p;
      }
      return *this;
   }
   // move semantics
   clone_ptr(clone_ptr&& p)
      : ptr(p.ptr) { p.ptr = 0; }
   clone_ptr& operator=(clone_ptr&& p)
   {
      if(this != &p)
      {
         std::swap(ptr, p.ptr);
         delete p.ptr;
         p.ptr = 0;
      }
      return *this;
   }
   // Other operations...
};

clone_ptr ожидал, что конструктор копий и семантика уступки, дублируя ресурсы при копировании. Обратите внимание, что копирование построения или назначения clone_ptr является относительно дорогой операцией:

clone_ptr<Base> p1(new Derived());
// ...
clone_ptr<Base> p2 = p1;  // p2 and p1 each own their own pointer

clone_ptr - это код, который вы можете найти в сегодняшних книгах на C++, за исключением части, обозначенной как move semantics. Эта часть реализована в терминах C++0x rvalue references. Вы можете найти хорошее введение и учебники по ссылкам на rvalue в этих документах:

Когда источник копии известен как rvalue (например: временный объект), можно избежать потенциально дорогого клон() операции с помощью указателя источника пилферинга (никто не заметит!). Конструктор движения выше делает именно это, оставляя r value в по умолчанию построенном состоянии. Оператор перемещения просто делает то же самое освобождение старых ресурсов.

Теперь, когда код пытается скопировать r value clone_ptr, или если этот код явно дает разрешение считать источник копии r value (с использованием boost::move), операция будет выполняться гораздо быстрее.

clone_ptr<Base> p1(new Derived());
// ...
clone_ptr<Base> p2 = boost::move(p1);  // p2 now owns the pointer instead of p1
p2 = clone_ptr<Base>(new Derived());   // temporary is moved to p2
}

Многие аспекты семантики перемещения могут быть эмулированы для компиляторов, не поддерживающих r value references и Boost.Move предлагает инструменты для этой цели. С Boost.Move мы можем написать clone_ptr, чтобы он работал как в компиляторах с rvalue-ссылками, так и в тех, кто соответствует C++03. Вам просто нужно следовать этим простым шагам:

  • Оставь конструктора копий, как есть.

Давайте посмотрим, как применяется к clone_ptr:

template <class T>
class clone_ptr
{
   private:
   // Mark this class copyable and movable
   BOOST_COPYABLE_AND_MOVABLE(clone_ptr)
   T* ptr;
   public:
   // Construction
   explicit clone_ptr(T* p = 0) : ptr(p) {}
   // Destruction
   ~clone_ptr() { delete ptr; }
   clone_ptr(const clone_ptr& p) // Copy constructor (as usual)
      : ptr(p.ptr ? p.ptr->clone() : 0) {}
   clone_ptr& operator=(BOOST_COPY_ASSIGN_REF(clone_ptr) p) // Copy assignment
   {
      if (this != &p){
         T *tmp_p = p.ptr ? p.ptr->clone() : 0;
         delete ptr;
         ptr = tmp_p;
      }
      return *this;
   }
   //Move semantics...
   clone_ptr(BOOST_RV_REF(clone_ptr) p)            //Move constructor
      : ptr(p.ptr) { p.ptr = 0; }
   clone_ptr& operator=(BOOST_RV_REF(clone_ptr) p) //Move assignment
   {
      if (this != &p){
         delete ptr;
         ptr = p.ptr;
         p.ptr = 0;
      }
      return *this;
   }
};

Q Вопрос: Что насчет типов, которые не владеют ресурсами? (E.g.std::комплекс?)

В этом случае никакой работы не требуется. Копировальный конструктор уже оптимален.


PrevUpHomeNext

Статья Implementing copyable and movable classes раздела The Boost C++ Libraries BoostBook Documentation Subset Chapter 23. Boost.Move может быть полезна для разработчиков на c++ и boost.




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.



:: Главная :: Chapter 23. Boost.Move ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-08-30 11:47:00
2025-05-19 17:22:21/0.029145956039429/1