当调用移动构造函数和默认构造函数时
When dose move constructor and default constructor called
我有这个代码
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;
...
}
在main()
MyString s1(MyString("test"));
我以为结果是这样的:
construct with C-char! <---- called by MyString("test")
move construct! <---- called by s1(...)
但我得到的是:
construct with C-char! <---- maybe called by MyString()
我想的步骤
MyString("test")
使用带 char*
的构造函数构造一个右值
- 构造s1(arg)
- 因为arg是右值,s1应该用移动构造函数来构造
但是我发现如果没有
std::move
. 就不会调用移动构造函数
为什么会这样?
如何在没有 std::move()
的情况下使用移动构造函数?
编译器:
Gnu C++ 9.3.0
Why is that happening?
C++17 起:因为 MyString("test")
是一个纯右值,并且语言说 s1
在这种情况下直接从 "test"
初始化。
C++17 之前:因为移动(和复制)构造函数的副作用不会 required/guaranteed 发生,这允许编译器通过不创建临时对象来进行优化。这种优化称为 copy elision,这就是您的编译器在此处所做的。
How to use move constructor without std::move()?
您不应该使用移动构造函数。最好不要创建多余的临时对象。您观察到的比您预期的要好。
如果您确实需要 std::move
(此处不适用),您不应该避免使用它。
因此,问题类似于“如何在不使用适当工具的情况下让我的管道泄漏?”。 1. 您不想让您的管道泄漏,并且 2. 如果您出于某种原因这样做,请使用适当的工具。
我有这个代码
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;
...
}
在main()
MyString s1(MyString("test"));
我以为结果是这样的:
construct with C-char! <---- called by MyString("test")
move construct! <---- called by s1(...)
但我得到的是:
construct with C-char! <---- maybe called by MyString()
我想的步骤
MyString("test")
使用带char*
的构造函数构造一个右值
- 构造s1(arg)
- 因为arg是右值,s1应该用移动构造函数来构造
但是我发现如果没有
std::move
. 就不会调用移动构造函数
为什么会这样?
如何在没有 std::move()
的情况下使用移动构造函数?
编译器:
Gnu C++ 9.3.0
Why is that happening?
C++17 起:因为 MyString("test")
是一个纯右值,并且语言说 s1
在这种情况下直接从 "test"
初始化。
C++17 之前:因为移动(和复制)构造函数的副作用不会 required/guaranteed 发生,这允许编译器通过不创建临时对象来进行优化。这种优化称为 copy elision,这就是您的编译器在此处所做的。
How to use move constructor without std::move()?
您不应该使用移动构造函数。最好不要创建多余的临时对象。您观察到的比您预期的要好。
如果您确实需要 std::move
(此处不适用),您不应该避免使用它。
因此,问题类似于“如何在不使用适当工具的情况下让我的管道泄漏?”。 1. 您不想让您的管道泄漏,并且 2. 如果您出于某种原因这样做,请使用适当的工具。