使用const_cast实现移动构造函数

时间:2014-08-01 01:53:29

标签: c++

我已阅读有关移动构造函数的this页面。在该文章中,它使用模板proxy来修改从函数返回的临时变量。

这是实施。

namespace detail {

    template <class T>
    struct proxy
    {
        T *resource_;
    };
} // detail

template <class T>
class MovableResource
{
private:
    T * resource_;

public:
    explicit MovableResource (T * r = 0) : resource_(r) { }
    ~MovableResource() throw() { delete resource_; }   // Assuming std:::auto_ptr like behavior.

    MovableResource (MovableResource &m) throw () // The "Move constructor" (note non-const parameter)
    : resource_ (m.resource_)
    {
        m.resource_ = 0; // Note that resource in the parameter is moved into *this.
    }

    MovableResource (detail::proxy<T> p) throw () // The proxy move constructor
    : resource_(p.resource_)
    {
        // Just copying resource pointer is sufficient. No need to NULL it like in the move constructor.
    }

    MovableResource & operator = (MovableResource &m) throw () // Move-assignment operator (note non-const parameter)
    {
        // copy and swap idiom. Must release the original resource in the destructor.
        MovableResource temp (m); // Resources will be moved here.
        temp.swap (*this);
        return *this;
    }

    MovableResource & operator = (detail::proxy<T> p) throw ()
    {
        // copy and swap idiom. Must release the original resource in the destructor.
        MovableResource temp (p);
        temp.swap(*this);
        return *this;
    }

    void swap (MovableResource &m) throw ()
    {
        std::swap (this->resource_, m.resource_);
    }

    operator detail::proxy<T> () throw () // A helper conversion function. Note that it is non-const
    {
        detail::proxy<T> p;
        p.resource_ = this->resource_;
        this->resource_ = 0;     // Resource moved to the temporary proxy object.
        return p;
    }
};

如果只是添加一个构造函数来获取const引用并使用const_cast来更改变量以实现这样的移动语义。

MovableResource(const MovableResource& m)
{
    MovableResource& afterM = const_cast<MovableResource&>(m);
    afterM.swap(*this);
}

这是否会引入未定义的行为?

2 个答案:

答案 0 :(得分:1)

在复制构造函数接口的引擎下实现移动语义只是在寻找麻烦。通过使用const_cast,您实际上是在欺骗您的界面的客户,使其相信您的构造函数在最终破坏其值时将保持m未经修改。请考虑以下代码:

const MovableResource first(/* Some resource 'A' */);
MovableResource second(first);
// 'first', supposedly 'const' now has potentially a different value!

答案 1 :(得分:0)

  

MovableResource(MovableResource&amp; m)throw()//&#34;移动构造函数&#34; (注意非const参数)

这不是移动构造函数,即复制构造函数。正确的 move 构造函数将右值引用作为输入:

MovableResource (MovableResource &&m) throw ()
  

MovableResource&amp; operator =(MovableResource&amp; m)throw()//移动赋值运算符(注意非const参数)

同样,这是一个复制赋值运算符。正确的移动赋值运算符将右值引用作为输入:

MovableResource & operator = (MovableResource &&m) throw ()