我在下面写了这个课,我有一个问题。函数sayHello()
返回一个在该行之后将被销毁的对象。但是,它不使用移动构造函数。它不是左值参考吗?为什么它不使用移动构造函数?
class FString {
private:
char *ptr;
public:
FString() : ptr(nullptr) {}
FString(const char *str) {
cout << "Called: FString(const char *str)\n";
//...
}
~FString() {
cout << "Called: ~FString()\n";
//...
}
FString(FString &&s) {
cout << "Called: FString(FString &&s)\n";
//...
}
};
FString sayHello() {
FString s("Hello World!");
return s;
}
int main() {
FString s("Hello World!");
FString s2(sayHello());
return 0;
}
输出:
Called: FString(const char *str)
Called: FString(const char *str)
Called: ~FString()
Called: ~FString()
感谢。
答案 0 :(得分:1)
此举已被取消;这是在各种情况下允许的优化,即使(如此处)移动构造函数具有副作用,因此省略调用会改变程序的行为。
具体地说,当程序使用临时(或局部变量,从函数返回时)直接初始化相同类型的对象时,可以通过对两个对象使用相同的存储来省略该移动。这里发生了这种情况,无论是在s
中使用sayHello
来初始化返回值,还是在使用该值初始化s2
时,都不需要移动或复制构造函数。
答案 1 :(得分:0)
编译器优化了对移动构造函数的需求。您是否尝试过禁用优化并检查结果是否相同?