在理解移动语义的同时在c ++程序中混淆操作

时间:2018-06-05 00:22:56

标签: c++ c++11 move-semantics rvalue-reference

我试图在c ++中掌握移动语义,rvalues,lvalues的概念,并且面临着一个问题。我首先看到这个受欢迎的答案 - 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被调用”)。它有什么作用?两个角色指针都不是datathat.data吗?为什么data没有改变价值? data现在不应该等于that.data 0x7fffac01bb80的值吗?相反,似乎某种memcopy正在发生,而that.data指向的字符串现在由data指向。任何有关正在发生的事情的提示都会有所帮助。

1 个答案:

答案 0 :(得分:2)

<div id="MyClockDisplay" class="clock"></div>的类型为&data。也就是说,它是指针的内存位置,用于存储某些char**的内存位置。

char不会使data = that.data;等于&data。它只会使&that.datadata相等。它们现在指向相同的that.data,但它们各自独立存在于内存中。

如果不是打印char的地址,而是print the address stored in data,您可以看到您正在窃取data所拥有的char数组。移动构造函数。