当剂量移动构造函数和默认构造函数被调用时

Tou*_*Liu 0 c++ constructor c++11

我有这个代码

class MyString {
    public:
        MyString();
        MyString(const char*);
        MyString(const String&);
        MyString(String&&) noexcept;
        ...
};

String::String()
{
    std::cout << "default construct!" <<std::endl;
}

String::String(const char* cb)
{
    std::cout << "construct with C-char!" <<std::endl;
    ...
}


String::String(const String& str)
{
    std::cout << "copy construct!" <<std::endl;
    ...
}

String::String(String&& str) noexcept
{
    std::cout << "move construct!" <<std::endl;
    ...
}

Run Code Online (Sandbox Code Playgroud)

main()

MyString s1(MyString("test"));
Run Code Online (Sandbox Code Playgroud)

我以为结果会是这样的:

用 C-char 构建!<---- 由 MyString("test")
移动构造调用!<---- 由 s1(...) 调用

但我得到的是这样的:

用 C-char 构建!<---- 可能由 MyString() 调用

我想到的步骤

  1. MyString("test")使用构造函数来构造右值char*
  2. 构造 s1( arg )
  3. 因为arg是一个右值,所以 s1 应该由 move 构造函数构造,但我发现 move 构造函数不会在没有std::move.

为什么会发生这种情况?
如何在没有 的情况下使用移动构造函数std::move()

编译器:
Gnu C++ 9.3.0

eer*_*ika 5

为什么会发生这种情况?

自 C++17 起:BecauseMyString("test")是纯右值,并且该语言表示在这种情况s1下直接初始化"test"

C++17 之前:因为不需要/保证发生移动(和复制)构造函数的副作用,这允许编译器通过不创建临时对象来进行优化。这种优化称为复制省略,这就是编译器在这里所​​做的。

如何在没有 std::move() 的情况下使用移动构造函数?

您不应该想使用移动构造函数。最好不要创建多余的临时对象。您观察到的情况比您预期的要好。

如果您确实需要std::move(此处不适用),您不应该避免使用它。

因此,这个问题类似于“如何在不使用适当工具的情况下使管道泄漏?”。1. 您不想让管道泄漏,并且 2. 如果由于某种原因发生泄漏,只需使用适当的工具即可。