Итак, как в наши дни пишутся базовые классы на C ++ 11? - PullRequest
3 голосов
/ 12 марта 2012

Обновление: я использую MSVC10, который не дает мне семантику перемещения по умолчанию

Допустим, я хочу создать обычный класс с парой элементов, не являющихся модулями;

class Foo {
NonPodTypeA a_;
NonPodTypeB b_;
}

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

Foo(const Foo& other) : a_(other.a_), b_(other.b_) {}
Foo& operator=(const Foo& other) { 
  Foo constructed(other);
  *this = std::move(constructed);
  return *this;
}

Затем я реализую конструктор move и move-присваивание, которое использует std :: swap вместо std :: move для всех членов, как они могли бы быть написаны до того, как была доступна семантика перемещения, так как семантика перемещения реализована, я могу опустить реализацию функции-члена подкачки:*

А вот и мой вопрос; Можно ли здесь что-то сделать более общим, предполагая, что я ничего не знаю о членах?

Например, конструктор перемещения не совместим с объявленными членами const, но если я реализуюконструктор перемещения как Foo(Foo&& other) : a_(std::move(other.a_)), b_(std::move(other.b_)){} Не могу быть уверен, что классы без семантики перемещения не копируются?Могу ли я каким-то умным образом использовать конструктор перемещения в задании перемещения?

Ответы [ 2 ]

6 голосов
/ 12 марта 2012

Эмм, ничего не делаю .Все эти вещи генерируются автоматически для вас 1 .Единственный раз, когда вам нужно написать их вручную, это когда класс обрабатывает ресурсы (а затем вам нужно следовать правилу трех ).Это также точно, как это было раньше.Единственное отличие теперь состоит в том, что после вы рассматривали Правило трех, вы можете захотеть реализовать элементы перемещения либо по семантическим (то есть для создания объектов только для перемещения), либо по причинам производительности (перемещения обычно выполняются быстрее, чем копии).


1.MSVC 10 не генерирует конструкторы перемещения автоматически.В этом случае вы, возможно, захотите написать членов движения самостоятельно: (

1 голос
/ 12 марта 2012

Учитывая ограничения MSVC10 и MSVC11 в том, что вы должны написать свои собственные конструкторы перемещения / операторы назначения перемещения, вот что я имею в виду. Я основал его на этом видео от Стефана Т. Лававея

http://channel9.msdn.com/Shows/Going+Deep/C9-Lectures-Stephan-T-Lavavej-Standard-Template-Library-STL-9-of-n

class Foo 
{
public:

    //Note: don't pass param by reference. Unified assignment operator
    Foo& operator=(Foo other)
    {
        other.swap(*this);
        return *this;
    }

    Foo(Foo&& other)
      : a_(std::move(other.a_),
        b_(std::move(other.b_){}

    Foo(Foo& other)
      : a_(other.a_),
        b_(other.b_){}

private:
    void swap(Foo& other)
    {
        using std::swap;
        swap(a_, other.a_);
        swap(b_, other.b_);
    }

private:
    NonPodTypeA a_;
    NonPodTypeB b_;
};
...