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$