c – 移动构造函数和继承

我试图理解在C11中移动构造函数和赋值操作的方式,但是我在委托父类时遇到问题.

代码

class T0
{
public:
    T0() { puts("ctor 0"); }
    ~T0() { puts("dtor 0"); }
    T0(T0 const&) { puts("copy 0"); }
    T0(T0&&) { puts("move 0"); }
    T0& operator=(T0 const&) { puts("assign 0"); return *this; }
    T0& operator=(T0&&) { puts("move assign 0"); return *this; }
};

class T : public T0
{
public:
    T(): T0() { puts("ctor"); }
    ~T() { puts("dtor"); }
    T(T const& o): T0(o) { puts("copy"); }
    T(T&& o): T0(o) { puts("move"); }
    T& operator=(T const& o) { puts("assign"); return static_cast<T&>(T0::operator=(o)); }
    T& operator=(T&& o) { puts("move assign"); return static_cast<T&>(T0::operator=(o)); }
};

int main()
{
    T t = std::move(T());
    return 0;
}

但是,当我在VS2012下编译并运行时,输出表示T0成员的左值版本被调用

ctor 0
ctor
copy 0  <--
move    <--
dtor
dtor 0
dtor
dtor 0

移动分配发生类似的情况(测试用例略有不同) – T的移动分配运算符调用T0的“正常”赋值运算符.

我究竟做错了什么?

解决方法

函数将rvalue引用作为参数的一个更令人困惑的事情是在内部将它们的参数视为左值.这是为了防止你在你的意思之前移动参数,但需要一些习惯.为了实际移动参数,你必须在其上调用std :: move(或std :: forward).所以你需要定义你的移动构造函数为:
T(T&& o): T0(std::move(o)) { puts("move"); }

您的移动分配运算符为:

T& operator=(T&& o) { puts("move assign"); return static_cast<T&>(T0::operator=(std::move(o))); }

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...