【发布时间】:2018-06-05 00:22:56
【问题描述】:
我试图在 C++ 中掌握移动语义、右值、左值的概念,但我正面临一个问题。我首先看的是这个流行的答案 - https://stackoverflow.com/a/3109981/9576161
我根据该回复编写了一个小程序,以了解发生了什么。我正在使用 g++(在 linux 上)和 -fno-elide-constructors 进行编译而无需编译器进行右值优化。
小程序如下:
#include <iostream>
#include <cstring>
using namespace std;
class string {
public:
char* data;
string (const char* p) {
cout << "Constructor 1 called\n";
size_t size = strlen(p) + 1;
data = new char[size];
cout << "this location is: " << this << endl;
memcpy (data,p,size);
}
string (string&& that) {
cout << "Constructor 2 called\n";
//cout << "data is " << data << " data location is: " << &data << endl;
cout << "data location is: " << &data << endl;
cout << "that.data is " << that.data << " that.data location is: " << &that.data << endl;
data = that.data;
that.data = nullptr;
cout << "this location is: " << this << " data is: " << data << endl;
cout << "data location is: " << &data << endl;
cout << "that.data location is: " << &that.data << endl;
}
~string() {
delete[] data;
cout << "Destructor called for object located at: " << this << endl;
}
void print() {
cout << "String is: " << data << endl;
}
};
int main () {
::string R = "12345";
cout << "R constructed and located at: " << &R << endl << endl;
return 0;
}
在运行程序时,我看到以下结果:
ubuntu@thinkpad:~/programming_practice/c_projects$ g++ -fno-elide-constructors move_semantics_short.cpp
ubuntu@thinkpad:~/programming_practice/c_projects$ ./a.out
Constructor 1 called
this location is: 0x7fffac01bb80
Constructor 2 called
data location is: 0x7fffac01bb78
that.data is 12345 that.data location is: 0x7fffac01bb80
this location is: 0x7fffac01bb78 data is: 12345
data location is: 0x7fffac01bb78
that.data location is: 0x7fffac01bb80
Destructor called for object located at: 0x7fffac01bb80
R constructed and located at: 0x7fffac01bb78
Destructor called for object located at: 0x7fffac01bb78
ubuntu@thinkpad:~/programming_practice/c_projects$
请注意第二个构造函数中的data = that.data 行(其中显示“构造函数2 被调用”)。它有什么作用? data 和 that.data 不是两个字符指针吗?为什么data 的价值没有变化? data 现在不应该等于that.data 的值,即0x7fffac01bb80 吗?相反,似乎某种memcopy 正在发生,that.data 指向的字符串现在由data 指向。任何有关正在发生的事情的提示都会有所帮助。
【问题讨论】:
-
data当然最好改变值。它只是窃取了that的data并将其清空以防止稍后发生意外。 -
您不需要编写整个类来测试两个指针在相互分配时的作用。
-
当
using namespace std;也被使用时,很高兴看到string作为类名。好主意! -
@user4581301 我不明白。
data是一个字符指针,不是吗?我没有正确打印指针的值吗?我认为这就是问题所在。而不是&data,我认为(void *)data将cout实际指针值。对吗? -
@slava 我正在使用
::。很抱歉造成混乱。
标签: c++ c++11 move-semantics rvalue-reference