Запутанная работа в программе на c ++ при понимании семантики перемещения - PullRequest
0 голосов
/ 05 июня 2018

Я пытаюсь понять концепцию семантики перемещения, значений, значений в с ++ и столкнулся с проблемой.Сначала я смотрю на этот популярный ответ - https://stackoverflow.com/a/3109981/9576161

Я написал небольшую программу, основанную на этом ответе, чтобы понять, что происходит.Я использую g++ (в Linux) и -fno-elide-constructors для компиляции без оптимизации значения r компилятором.

Вот небольшая программа:

#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.Любые намеки на то, что происходит, будут полезны.

1 Ответ

0 голосов
/ 05 июня 2018

Тип &data равен char**.То есть, это место в памяти указателя, которое хранит место в памяти некоторого char.

data = that.data;, которое не делает &data равным &that.data.Это просто делает data и that.data равными.Теперь они указывают на один и тот же char, но каждый из них существует независимо в памяти.

Если вместо печати адреса data вы напечатаете адрес , хранящийся в data, вы можете видеть, что вы крадете массив char s, которым владел that в вашем конструкторе перемещения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...