C++ 如何为这个派生类编写移动赋值函数?

C++ 如何为这个派生类编写移动赋值函数?,c++,visual-studio,c++11,move-semantics,visual-studio-2013,C++,Visual Studio,C++11,Move Semantics,Visual Studio 2013,,我需要为派生类提供自己的移动构造函数和移动赋值。但是,我不知道如何为基类调用适当的move函数 代码如下: #include <utility> // Base class; movable, non-copyable class shader { public: virtual ~shader() { if (id_ != INVALID_SHADER_ID) {

,我需要为派生类提供自己的移动构造函数和移动赋值。但是,我不知道如何为基类调用适当的move函数

代码如下:

#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;
}
#包括
//基类;可移动的,不可复制的
类着色器
{
公众:
虚拟着色器()
{
if(id_!=无效的\u着色器\u id)
{
//清理
}
}
//移动分配
着色器和运算符=(着色器和其他)
{
//布雷特·黑尔(Brett Hale)下面的评论指出了这里的资源泄漏。
//原件:
//id_uu=other.id_uu;
//other.id=无效的着色器id;
//固定的:
std::swap(id_u,other.id_u);
归还*这个;
}
//移动构造函数
着色器(着色器和其他)
{
*这=标准::移动(其他);
}
受保护的:
//构造无效的着色器。
着色器()
:id{无效的着色器{u id}
{}
//构造一个有效的着色器
着色器(常量字符*路径)
{
id=1;
}
私人:
//着色器是不可复制的
着色器(常量着色器&)=删除;
着色器和运算符=(常量着色器&)=删除;
静态常量int无效\u着色器\u ID=0;
int-id_2;;
//…其他成员变量。
};
//派生类
类顶点_着色器最终:公共着色器
{
公众:
//构造无效的顶点着色器。
顶点_着色器()
:着色器{}
{}
顶点着色器(常量字符*路径)
:着色器{path}
{}
//下面这行代码适用于g++,但不适用于Visual Studio 2013(请参见顶部的链接)。。。
//顶点着色器&操作符=(顶点着色器&&)=默认值;
//…所以我必须自己写。
顶点着色器和操作符=(顶点着色器和)
{
//这里有什么?
归还*这个;
}
顶点着色器(顶点着色器和其他)
{
*这=标准::移动(其他);
}
私人:
//顶点着色器不可复制
顶点着色器(常量顶点着色器&)=删除;
顶点着色器和运算符=(常量顶点着色器和)=删除;
};
int main(int argc,char*argv[])
{
顶点v;
//后来
v=顶点着色器{“顶点着色器.glsl”};
返回0;
}

派生类中的移动赋值函数应该是什么样子?

您只需要调用基类移动赋值运算符:

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

关于使用
*this=std::move(other)
实现move构造函数的有趣帖子:@Troy,感谢您的反馈。正是那篇微软的文章让我首先改变了这种风格。我想这是忽视微软的另一个原因。:)它是有效的,另一个问题只是概述了它否定了移动分配的一些效率优势。需要考虑的是:)您的
着色器
移动分配操作符可能存在潜在的资源泄漏。如果
id\u
是有效的资源,则应在获取
other.id\u
资源之前释放它。也许我们需要这个问题中的[QLD]标记!编译器是否可以直接接受基类,如
顶点着色器和操作符=(着色器和rhs){…}
?这是否得到支持?