为什么显式调用基移动构造函数实际上调用基复制构造函数?

发布于 2024-12-27 08:54:18 字数 818 浏览 4 评论 0原文

我试图通过派生类 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

老娘不死你永远是小三 2025-01-03 08:54:18

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

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

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

In the context of your Derived class the parameter rhs clearly has a name. Thus, it must be an lvalue, it can't be an rvalue. However, the T&& only binds to rvalues. If you want to call the base class's move constructor you need to use code like this:

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

This will call the move constructor of Base and move the Base portion of rhs. Since Base doesn't know anything about the Derived members, the Base move constructor won't move anything added by Derived.

彡翼 2025-01-03 08:54:18

仅当满足以下两个条件时,签名中带有 && 的构造函数或任何其他函数或方法才有资格被编译器选择:

  • 您传入的表达式的数据类型是 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:

  • The datatype of the expression you are passing in is T&& or T. - i.e. T& won't be accepted
  • and it actually has to be an rvalue - e.g. returned (by value T or by T&&) 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 as move) before it can be considered eligible to be passed into a function that requires an &&.

醉梦枕江山 2025-01-03 08:54:18

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文