为什么这个移动构造函数不起作用? - C++11

3
我已经编写了下面发布的代码。我希望能够在LargeClass实例之间移动向量的内容。使用了移动构造函数,但是只得到了复制的结果。
为什么移动语义在此处不能按预期工作?
代码:
#include <iostream>
#include <vector>

class LargeClass
{
public:
    explicit LargeClass (void): numbers(20, 10) 
    {
    }
    LargeClass (const LargeClass &rhs): numbers(rhs.numbers)
    { 
        std::cout << "Using LargeClass copy constructor" << '\n';
    }
    LargeClass (const LargeClass &&rhs): numbers(std::move(rhs.numbers))
    { 
        std::cout << "Using LargeClass move constructor" << '\n';
    }

    const int* getNumbersAddress(void) const
    {
        return (numbers.data());
    }

private:
    std::vector<int> numbers;
};

int main()
{
    LargeClass l1;
    std::cout << "l1 vector address: " << l1.getNumbersAddress() << '\n';

    LargeClass l2(l1);
    std::cout << "l1 vector address: " << l1.getNumbersAddress() << '\n';
    std::cout << "l2 vector address: " << l2.getNumbersAddress() << '\n';

    LargeClass l3 = std::move(l2); 
    std::cout << "l1 vector address: " << l1.getNumbersAddress() << '\n';
    std::cout << "l2 vector address: " << l2.getNumbersAddress() << '\n';
    std::cout << "l3 vector address: " << l3.getNumbersAddress() << '\n';

    return 0;
}

可能的输出:

可能的输出:

l1 vector address: 0x18ce010
Using LargeClass copy constructor
l1 vector address: 0x18ce010
l2 vector address: 0x18ce070
Using LargeClass move constructor
l1 vector address: 0x18ce010
l2 vector address: 0x18ce070
l3 vector address: 0x18ce0d0

它将内容移动到地址之间,但容器的地址仍然保持不变,对吗? - user1585121
3
移动构造函数的语法应该是 LargeClass ( LargeClass &&rhs ) - P0W
2
@POW请将此作为答案发布。多么愚蠢的错误...谢谢! - Sebastian Kramer
2个回答

6
rvalue 引用的 const 形式没有意义,因为你想要修改它们(你想要将它们“移动”)。在 C++ 中以 const 形式创建的对象位于只读内存中,无法抓取/修改内部资源。

移动构造函数的语法 通常 应该是

  • class_name ( class_name && )

所以使用:

LargeClass ( LargeClass&& rhs )


3
尽管以 const LargeClass&& 为参数的构造函数在技术上被称为移动构造函数(12.8/3)(这很令人困惑,但在[C++11: 12.8/3]中明确说明),但它几乎没有用处;显然您不能从 const 表达式中进行移动,因为您不能修改 const 的内容,而移动则意味着要更改源!特别是,您无法实际地从一个 const 向量中移动,这也是为什么此处未发生移动的原因,以及您看到的现象。

一个更有用的移动构造函数如下所示:

LargeClass(LargeClass&& rhs)

严格按照规定,它确实是一个移动构造函数。虽然不是非常有用,但仍然如此。 - Angew is no longer proud of SO
@Angew:True(12.8/3),这很奇怪。 - Lightness Races in Orbit
2
移动构造函数确实被调用了。它只是没有做 OP 所期望的事情。 - Casey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接