Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I write the move assignment function for this derived class?

Tags:

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?

like image 625
x-x Avatar asked Oct 01 '13 06:10

x-x


People also ask

How do you write a move assignment operator?

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.

What does move operator do in C++?

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.

What is the move constructor in C++?

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.

How do you call a move constructor?

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.


1 Answers

You just need to call the base class move assignment operator:

    vertex_shader& operator=(vertex_shader&& rhs)
    {
        shader::operator=(std::move(rhs));
        return *this;
    }
like image 96
goji Avatar answered Sep 20 '22 20:09

goji