2013-10-01 2 views
11

Due to this bug in Visual Studio 2013, мне нужно предоставить свой собственный конструктор перемещения и переместить назначение для производного класса. Однако я не знаю, как вызвать соответствующие функции перемещения для базового класса.Как написать функцию назначения перемещения для этого производного класса?

Вот код:

#include <utility> 

// Base class; movable, non-copyable 
class shader 
{ 
    public: 
     virtual ~shader() 
     { 
      if (id_ != INVALID_SHADER_ID) 
      { 
       // Clean up 
      } 
     } 

     // Move assignment 
     shader& operator=(shader&& other) 
     { 
      // Brett Hale's comment below pointed out a resource leak here. 
      // Original: 
      // id_ = other.id_; 
      // other.id_ = INVALID_SHADER_ID; 
      // Fixed: 
      std::swap(id_, other.id_); 
      return *this; 
     } 

     // Move constructor 
     shader(shader&& other) 
     { 
      *this = std::move(other); 
     } 

    protected: 
     // Construct an invalid shader. 
     shader() 
      : id_{INVALID_SHADER_ID} 
     {} 

     // Construct a valid shader 
     shader(const char* path) 
     { 
      id_ = 1; 
     } 

    private: 
     // shader is non-copyable 
     shader(const shader&) = delete; 
     shader& operator=(const shader&) = delete; 

     static const int INVALID_SHADER_ID = 0; 

     int id_; 
     // ...other member variables. 
}; 

// Derived class 
class vertex_shader final : public shader 
{ 
    public: 
     // Construct an invalid vertex shader. 
     vertex_shader() 
      : shader{} 
     {} 

     vertex_shader(const char* path) 
      : shader{path} 
     {} 

     // The following line works in g++, but not Visual Studio 2013 (see link at top)... 
     //vertex_shader& operator=(vertex_shader&&) = default; 

     // ... so I have to write my own. 
     vertex_shader& operator=(vertex_shader&&) 
     { 
      // What goes here? 
      return *this; 
     } 

     vertex_shader(vertex_shader&& other) 
     { 
      *this = std::move(other); 
     } 

    private: 
     // vertex_shader is non-copyable 
     vertex_shader(const vertex_shader&) = delete; 
     vertex_shader& operator=(const vertex_shader&) = delete; 
}; 

int main(int argc, char* argv[]) 
{ 
    vertex_shader v; 

    // later on 
    v = vertex_shader{ "vertex_shader.glsl" }; 

    return 0; 
} 

Что следует функция присваивания двигаться в производном классе выглядеть?

+2

Интересный пост об использовании '* это = зЬй :: ход (другие)' реализовать конструктор перемещения: HTTP: // StackOverflow. com/questions/17118256/implementation-move-constructor-by-call-move-assign-operator – goji

+0

@Troy, спасибо за отзыв. Это была статья Microsoft, в которой я впервые изменил этот стиль. Еще одна причина игнорировать Microsoft, я полагаю. :) –

+0

Он работает, другой вопрос только очерчивает, что он отрицает некоторые преимущества эффективности назначения перемещения. Просто подумать о том, что я думаю :) – goji

ответ

23

Вам просто нужно вызвать базовый класс оператор присваивания шаг:

vertex_shader& operator=(vertex_shader&& rhs) 
    { 
     shader::operator=(std::move(rhs)); 
     return *this; 
    }