在理解移动语义的同时混淆c++程序中的操作
Confusing operation in c++ program while understanding move semantics
我试图掌握 c++ 中移动语义、右值、左值的概念,但遇到了一个问题。我首先查看这个流行的答案 -
我根据那个回复写了一个小程序来了解是怎么回事。我正在使用 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
行(它表示 "Constructor 2 is called")。它有什么作用? data
和 that.data
不都是字符指针吗?为什么 data
的值没有变化? data
现在不应该等于 that.data
的值 0x7fffac01bb80
吗?相反,似乎发生了某种 memcopy
,that.data
指向的字符串现在由 data
指向。任何有关正在发生的事情的提示都会有所帮助。
&data
的类型是char**
。也就是存放一些char
.
的内存位置的指针的内存位置
data = that.data;
不会使 &data
等于 &that.data
。它只是让 data
和 that.data
相等。它们现在指向同一个 char
,但它们各自独立存在于内存中。
如果您 print the address stored in data
没有打印 data
的地址,您可以看到您正在窃取 that
拥有的 char
数组在你的移动构造函数中。
我试图掌握 c++ 中移动语义、右值、左值的概念,但遇到了一个问题。我首先查看这个流行的答案 -
我根据那个回复写了一个小程序来了解是怎么回事。我正在使用 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
行(它表示 "Constructor 2 is called")。它有什么作用? data
和 that.data
不都是字符指针吗?为什么 data
的值没有变化? data
现在不应该等于 that.data
的值 0x7fffac01bb80
吗?相反,似乎发生了某种 memcopy
,that.data
指向的字符串现在由 data
指向。任何有关正在发生的事情的提示都会有所帮助。
&data
的类型是char**
。也就是存放一些char
.
data = that.data;
不会使 &data
等于 &that.data
。它只是让 data
和 that.data
相等。它们现在指向同一个 char
,但它们各自独立存在于内存中。
如果您 print the address stored in data
没有打印 data
的地址,您可以看到您正在窃取 that
拥有的 char
数组在你的移动构造函数中。