【问题标题】:How do I write the move assignment function for this derived class?如何为这个派生类编写移动赋值函数?
【发布时间】:2013-10-07 05:05:07
【问题描述】:

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

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

【问题讨论】:

  • 关于使用*this = std::move(other)实现移动构造函数的有趣帖子:stackoverflow.com/questions/17118256/…
  • @Troy,感谢您的反馈。正是那篇微软文章让我首先改变了这种风格。我想忽略微软的另一个原因。 :)
  • 它有效,另一个问题只是概述了它否定了移动分配的一些效率优势。我想只是想一想:)
  • 您的shader 移动赋值运算符可能存在潜在的资源泄漏。如果id_ 是有效资源,则应在获取other.id_ 资源之前释放它。也许我们在这个问题中需要 [QLD] 标签!

标签: c++ visual-studio c++11 move-semantics visual-studio-2013


【解决方案1】:

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

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

【讨论】:

  • 编译器能否像vertex_shader&amp; operator=(shader&amp;&amp; rhs) { ... }一样直接接受基类?甚至支持吗?
猜你喜欢
  • 2014-08-04
  • 1970-01-01
  • 1970-01-01
  • 2013-11-18
  • 1970-01-01
  • 2016-10-06
  • 2013-10-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多