c++11 move 不生效?
c++11 move not take effective?
我测试了c++11的move函数,没有生效。谁能告诉我为什么?谢谢。代码如下:
class Base {
public:
Base() { cout << "Base" << endl;}
~Base() { cout << "~Base" << endl;}
Base(const Base& base) { cout << "Copy" << endl; }
Base& operator=(const Base& base) {cout << "operator=" << endl;}
Base(Base&& base) { cout << "move" << endl;}
Base& operator=(Base&& base) { cout << "move=" << endl;}
};
Base b;
Base&& GetResult() {
return std::move(b);
}
int main() {
Base&& tmp = GetResult();
cout << &b << endl;
cout << &tmp << endl;
}
输出:
Base
0x6013a0
0x6013a0
~Base
为什么 move copy
和 move operator=
不被调用?为什么地址是一样的?
Why move copy and move operator= not be called ?
我假设 "move copy" 是指 "move constructor"。移动赋值运算符不被调用,因为你从不使用赋值运算符。
没有移动(也没有复制),因为 Base&&
是一个 引用 (具体来说是一个右值引用)。引用引用/指向一个对象——它们不包含对象的状态。初始化引用时,不会复制或移动任何对象。
And why address is the same ?
当 address-of 运算符应用于引用时,您将获得引用对象的地址。
让我们暂时忽略移动语义,只考虑熟悉的 C++98 复制构造函数。给定以下代码,您期望得到什么输出?
class Base {
public:
Base() { cout << "Base" << endl;}
~Base() { cout << "~Base" << endl;}
Base(const Base& base) { cout << "Copy" << endl; }
Base& operator=(const Base& base) {cout << "operator=" << endl;}
};
Base b;
Base& GetResult() {
return b;
}
int main() {
Base& tmp = GetResult();
cout << &b << endl;
cout << &tmp << endl;
}
当然,您会期望调用 Base
默认构造函数,然后是打印两次的 b
地址,然后是 Base
析构函数。原因是因为您只构建了一个 Base
实例,并且从不复制它——您只是在使用引用。
你的例子也是如此。您使用的是右值引用而不是左值引用,但要点是相同的——只有一个 Base
变量,并且不会发生任何复制或移动。如果你想见证动作语义,你可以尝试这样的事情:
Base getBase() {
return Base{};
}
int main() {
Base tmp = getBase();
Base other = std::move(tmp);
}
(getBase()
的移出可能会被编译器优化掉,但你仍然应该看到第二个。)
为了补充现有的优秀答案,我认为这里的主要混淆点是 std::move
的作用。
std::move
不动.
它的名字非常糟糕。
它只会给你一个 xvalue,指的是你给它的任何东西;此 xvalue 将绑定到右值引用,而左值则不会。这意味着 std::move
的结果可以 提供给移动构造函数或移动赋值运算符。但是,它不会为您做这些,您也不会在这里做。
Given such strong criticism for the naming, surely you have an alternative suggestion
– user2079303
这是一个老生常谈的话题,但是 the creator of C++ suggests std::rval
, and one of the architects of modern C++ suggests std::rvalue_cast
(即使你实际上得到了一个 xvalue)。
就我个人而言,我认为 std::moveable
会是一个很好的中间立场。
我测试了c++11的move函数,没有生效。谁能告诉我为什么?谢谢。代码如下:
class Base {
public:
Base() { cout << "Base" << endl;}
~Base() { cout << "~Base" << endl;}
Base(const Base& base) { cout << "Copy" << endl; }
Base& operator=(const Base& base) {cout << "operator=" << endl;}
Base(Base&& base) { cout << "move" << endl;}
Base& operator=(Base&& base) { cout << "move=" << endl;}
};
Base b;
Base&& GetResult() {
return std::move(b);
}
int main() {
Base&& tmp = GetResult();
cout << &b << endl;
cout << &tmp << endl;
}
输出:
Base
0x6013a0
0x6013a0
~Base
为什么 move copy
和 move operator=
不被调用?为什么地址是一样的?
Why move copy and move operator= not be called ?
我假设 "move copy" 是指 "move constructor"。移动赋值运算符不被调用,因为你从不使用赋值运算符。
没有移动(也没有复制),因为 Base&&
是一个 引用 (具体来说是一个右值引用)。引用引用/指向一个对象——它们不包含对象的状态。初始化引用时,不会复制或移动任何对象。
And why address is the same ?
当 address-of 运算符应用于引用时,您将获得引用对象的地址。
让我们暂时忽略移动语义,只考虑熟悉的 C++98 复制构造函数。给定以下代码,您期望得到什么输出?
class Base {
public:
Base() { cout << "Base" << endl;}
~Base() { cout << "~Base" << endl;}
Base(const Base& base) { cout << "Copy" << endl; }
Base& operator=(const Base& base) {cout << "operator=" << endl;}
};
Base b;
Base& GetResult() {
return b;
}
int main() {
Base& tmp = GetResult();
cout << &b << endl;
cout << &tmp << endl;
}
当然,您会期望调用 Base
默认构造函数,然后是打印两次的 b
地址,然后是 Base
析构函数。原因是因为您只构建了一个 Base
实例,并且从不复制它——您只是在使用引用。
你的例子也是如此。您使用的是右值引用而不是左值引用,但要点是相同的——只有一个 Base
变量,并且不会发生任何复制或移动。如果你想见证动作语义,你可以尝试这样的事情:
Base getBase() {
return Base{};
}
int main() {
Base tmp = getBase();
Base other = std::move(tmp);
}
(getBase()
的移出可能会被编译器优化掉,但你仍然应该看到第二个。)
为了补充现有的优秀答案,我认为这里的主要混淆点是 std::move
的作用。
std::move
不动.
它的名字非常糟糕。
它只会给你一个 xvalue,指的是你给它的任何东西;此 xvalue 将绑定到右值引用,而左值则不会。这意味着 std::move
的结果可以 提供给移动构造函数或移动赋值运算符。但是,它不会为您做这些,您也不会在这里做。
Given such strong criticism for the naming, surely you have an alternative suggestion
– user2079303
这是一个老生常谈的话题,但是 the creator of C++ suggests std::rval
, and one of the architects of modern C++ suggests std::rvalue_cast
(即使你实际上得到了一个 xvalue)。
就我个人而言,我认为 std::moveable
会是一个很好的中间立场。