c+中的混淆运算+;在理解移动语义的同时编程 我试图掌握C++中的移动语义、rValuy、LValm的概念,并面临一个问题。我首先看到的是这个流行的答案-
我根据这个回复写了一个小程序来了解发生了什么。我正在使用c+中的混淆运算+;在理解移动语义的同时编程 我试图掌握C++中的移动语义、rValuy、LValm的概念,并面临一个问题。我首先看到的是这个流行的答案-,c++,c++11,move-semantics,rvalue-reference,C++,C++11,Move Semantics,Rvalue Reference,我根据这个回复写了一个小程序来了解发生了什么。我正在使用g++(在linux上)和-fno-elide构造函数进行编译,无需编译器进行右值优化 以下是小程序: #include <iostream>
g++
(在linux上)和-fno-elide构造函数
进行编译,无需编译器进行右值优化
以下是小程序:
#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;
}
请注意第二个构造函数中的行
data=that.data
(其中表示“调用了构造函数2”)。它有什么作用?data
和这两个字符指针不是都是.data
吗?为什么数据
的值没有变化?data
现在是否应该等于.data的值,即0x7fffac01bb80
?相反,它似乎出现了某种类型的memcopy
,而that.data
指向的字符串现在由data
指向。任何关于正在发生的事情的提示都会很有帮助。数据的类型是char**
。也就是说,指针的内存位置存储了一些字符的内存位置
data=that.data
不会使&data
等于&that.data
。它只是使数据
和数据
相等。它们现在指向相同的char
,但它们各自独立存在于内存中
如果不打印数据
的地址,您可以看到您正在窃取移动构造函数中属于的字符
的数组。数据
的类型是字符**
。也就是说,指针的内存位置存储了一些字符的内存位置
data=that.data
不会使&data
等于&that.data
。它只是使数据
和数据
相等。它们现在指向相同的char
,但它们各自独立存在于内存中
如果不打印数据
的地址,您可以看到您正在窃取移动构造函数中属于的字符
数组。数据
当然最好更改值。它只是窃取了的数据,并将其置空以防止以后发生意外。您不需要编写整个类来测试两个指针在分配给彼此时所做的事情。在使用命名空间std时,将字符串作为类名是一件非常好的事情代码>也被使用。好主意@用户4581301我不明白<代码>数据
是一个字符指针,不是吗?我是否没有正确打印指针的值?我认为这就是问题所在。我认为(void*)数据将转换为实际的指针值,而不是&data
。是吗?@slava我用的是:
。抱歉造成混淆。数据
请务必更改值。它只是窃取了的数据,并将其置空以防止以后发生意外。您不需要编写整个类来测试两个指针在分配给彼此时所做的事情。在使用命名空间std时,将字符串作为类名是一件非常好的事情代码>也被使用。好主意@用户4581301我不明白<代码>数据
是一个字符指针,不是吗?我是否没有正确打印指针的值?我认为这就是问题所在。我认为(void*)数据将转换为实际的指针值,而不是&data
。是吗?@slava我用的是:
。很抱歉给你带来了困惑。
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$