2013-10-01 12 views
11

Due to this bug in Visual Studio 2013, Muszę podać własny konstruktor ruchu i przenieść zadanie dla klasy pochodnej. Jednak nie wiem, jak wywołać odpowiednie funkcje przenoszenia dla klasy bazowej.Jak napisać funkcję przypisania przeniesienia dla tej klasy pochodnej?

Oto kod:

#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; 
} 

Co powinien funkcja przypisania ruch w klasie pochodnej wyglądać?

+2

ciekawy post na temat używania '* = std :: ten ruch (Inne)' wdrożyć konstruktora ruch: http: // stackoverflow. com/questions/17118256/implementation-move-constructor-by-calling-move-assignment-operator – goji

+0

@Troy, dzięki za informację zwrotną. Właśnie ten artykuł Microsoftu skłonił mnie do zmiany tego stylu. Kolejny powód, aby ignorować Microsoft. :) –

+0

To działa, inne pytanie tylko podkreśla, że ​​neguje niektóre z korzyści wydajności zadania przeniesienia. Po prostu o czym pomyśleć :) – goji

Odpowiedz

23

Wystarczy zadzwonić do klasy bazowej operatora przypisania ruch:

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