3

我正在尝试通过派生类 move ctor 显式调用基类 move ctor,但是,令人惊讶!,这实际上调用了基类复制ctor而不是基类移动ctor。

我在std::move()对象上使用函数来确保正在调用派生的移动 ctor!

编码:

class Base
{
public:
    Base(const Base& rhs){ cout << "base copy ctor" << endl; }
    Base(Base&& rhs){ cout << "base move ctor" << endl; }
};

class Derived : public Base
{
public:

    Derived(Derived&& rhs) : Base(rhs) { cout << "derived move ctor"; }
    Derived(const Derived& rhs) : Base(rhs) { cout << "derived copy ctor" << endl; }
};

int main()
{
    Derived a;
    Derived y = std::move(a); // invoke move ctor
    cin.ignore();
    return 0;
}

节目输出:

基础复制因子

派生移动子

如您所见,基类 move ctor 被遗忘了,那么我该如何称呼它呢?

4

3 回答 3

5

在您的Derived类的上下文中,参数rhs显然有一个名称。因此,它必须是左值,不能是右值。但是,T&&唯一绑定到右值。如果要调用基类的移动构造函数,则需要使用如下代码:

Derived(Derived&& rhs): Base(std::move(rhs)) { std::cout << "derived move ctor"; }

这将调用 的移动构造函数Base并移动 的Base部分rhs。由于对成员Base一无所知,因此移动构造函数不会移动由 . 添加的任何内容。DerivedBaseDerived

于 2012-01-17T00:42:06.017 回答
2

只有当这两个条件都成立时,其签名中的构造函数或任何其他函数或方法&&才有资格被编译器选择:

  • 您传入的表达式的数据类型是T&&or T。- 即T&不被接受
  • 实际上必须是一个右值 - 例如从函数返回(按值T或按T&&)。

move(rhs)满足这两个条件。rhs是正确的类型,但它实际上必须从函数(例如move)返回,然后才能被认为有资格传递给需要&&.

于 2012-01-17T00:59:04.153 回答
1

如果使用基类移动构造函数,则派生构造函数可以访问移动对象。这很危险,因此除非您明确告诉编译器您已完成使用该对象并且可以安全移动,否则它不会发生。

于 2012-01-17T00:45:38.953 回答