我试图通过派生类移动ctor显式调用基类移动ctor但是, surprise!,实际上调用基类复制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;
}
计划输出:
base copy ctor
派生移动ctor
如你所见,基类移动ctor正在被遗忘,所以我该怎么称呼它?
答案 0 :(得分:5)
在Derived
类的上下文中,参数rhs
显然有一个名称。因此,它必须是左值,它不能是右值。但是,T&&
仅绑定到右值。如果要调用基类的移动构造函数,则需要使用如下代码:
Derived(Derived&& rhs): Base(std::move(rhs)) { std::cout << "derived move ctor"; }
这将调用Base
的移动构造函数并移动Base
的{{1}}部分。由于rhs
对Base
成员一无所知,Derived
移动构造函数不会移动Base
添加的任何内容。
答案 1 :(得分:2)
如果这两个条件都成立,编译器中只有&&
的构造函数或任何其他函数或方法才有资格被编译器选中:
T&&
或T
。 - 即不接受T&
T
或T&&
)。 move(rhs)
满足这两个条件。 rhs
属于正确的类型,但实际上必须从函数(例如move
)返回,才能认为它有资格传递给需要&&
的函数
答案 2 :(得分:1)
如果使用了基类移动构造函数,则派生的构造函数可以访问移动的对象。这很危险,所以除非你明确告诉编译器你已经完成了使用该对象并且移动是安全的,否则它不会发生。