为什么显式调用基移动构造函数实际上调用基复制构造函数?
我试图通过派生类 move ctor 显式调用基类 move ctor,但是,惊讶!,这实际上调用的是基类 copy ctor,而不是基类 move ctor。
我在对象上使用 std::move() 函数以确保派生的移动向量被调用!
代码:
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;
}
程序输出:
基本复制因子
派生移动向量
被遗忘了,那么我该如何调用它呢?
I'm trying to call the base class move ctor explicitly through derived class move ctor but, surprise!, that actually calls the base class copy ctor NOT the base class move ctor.
I'm using std::move()
function on an object to be sure that the derived move ctor is being invoked!
The code:
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;
}
PROGRAM OUTPUT:
base copy ctor
derived move ctor
As you see, the base class move ctor is being forgotten, so how do I call it?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
在
Derived
类的上下文中,参数rhs
显然有一个名称。因此,它必须是左值,不能是右值。但是,T&&
仅绑定到右值。如果要调用基类的移动构造函数,则需要使用如下代码:这将调用
Base
的移动构造函数并移动rhs 的
。由于Base
部分Base
对Derived
成员一无所知,因此Base
移动构造函数不会移动Derived
添加的任何内容代码>.In the context of your
Derived
class the parameterrhs
clearly has a name. Thus, it must be an lvalue, it can't be an rvalue. However, theT&&
only binds to rvalues. If you want to call the base class's move constructor you need to use code like this:This will call the move constructor of
Base
and move theBase
portion ofrhs
. SinceBase
doesn't know anything about theDerived
members, theBase
move constructor won't move anything added byDerived
.仅当满足以下两个条件时,签名中带有
&&
的构造函数或任何其他函数或方法才有资格被编译器选择:T&&
或T
。 - 即T&
不会被接受T
或通过T&&
) 来自函数。move(rhs)
满足这两个条件。rhs
是正确的类型,但它实际上必须从函数(例如move
)返回,然后才能被认为有资格传递到需要的函数中一个&&
。A constructor, or any other function or method, with
&&
in its signature will only be eligible to be selected by the compiler if both these conditions hold:T&&
orT
. - i.e.T&
won't be acceptedT
or byT&&
) from a function.move(rhs)
satisfies both of these conditions.rhs
is of the right type, but it actually has to be returned from a function (such asmove
) before it can be considered eligible to be passed into a function that requires an&&
.如果使用基类移动构造函数,则派生构造函数可以访问移出的对象。这很危险,因此除非您明确告诉编译器您已完成对对象的使用并且可以安全移动,否则这种情况不会发生。
If the base class move constructor were used, then the derived constructor could access a moved-from object. That's dangerous, so it won't happen unless you explicitly tell the compiler that you're done using the object and it's safe to move.