Due to this bug in Visual Studio 2013, I need to provide my own move constructor and move assignment for a derived class. However, I don't know how to call the appropriate move functions for the base class.
Here's the code:
#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;
}
What should the move assignment function in the derived class look like?
To create a move assignment operator for a C++ class In the move assignment operator, add a conditional statement that performs no operation if you try to assign the object to itself. In the conditional statement, free any resources (such as memory) from the object that is being assigned to.
In the C++ programming language, the move assignment operator = is used for transferring a temporary object to an existing object. The move assignment operator, like most C++ operators, can be overloaded. Like the copy assignment operator it is a special member function.
A move constructor allows the resources owned by an rvalue object to be moved into an lvalue without creating its copy. An rvalue is an expression that does not have any memory address, and an lvalue is an expression with a memory address.
The syntax of forcing use of move constructor is: class_name ( class_name && ) = default; As we can see from the output, we can ask the compiler to use move constructor even though we defined destructor.
You just need to call the base class move assignment operator:
vertex_shader& operator=(vertex_shader&& rhs)
{
shader::operator=(std::move(rhs));
return *this;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With