2014-11-20 2 views
0

В этом фрагменте кода у меня есть std::map в структуре. И тогда я просто назначаю экземпляр структуры другому. Обратите внимание: структура не имеет оператора присваивания. В таком случае должен ли я ожидать, что оператор присваивания карты будет вызываться или компилятор только мелкой копии памяти содержит структуры?Назначение структуры, которая имеет элемент std :: map

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    struct vectstruct 
    { 
     std::map<int, double> mymap; 
    }; 
    vectstruct vs1, vs2; 
    vs1.mymap[7] = 54.321; 
    vs2 = vs1; // Should call assignment operator of map vs2.mymap 
    vs1.mymap[7] = 65.432; 
    return 0; 
} 

Я попытался это с Microsft Visual Studio и в конце программы я вижу значение vs2.mymap[7] остается 54.321, как и ожидалось. Но мне нравится знать, правильно ли это с помощью стандартов C++ или мне нужно написать оператор присваивания vectstruct, в котором я бы явно вызывал оператор присваивания карты?

+1

В общем случае не записывайте конструкторы копирования или операторы присваивания, если все члены данных ведут себя хорошо (как в этом случае). Вам нужно только это, когда вы управляете членом (например: указатель) (см. Правило none, правило три, правило пять (C++ 11)) –

ответ

2

В качестве стиля вы должны объявить и определить свои типы за пределами main.

При этом, если вы не предоставляете оператора присваивания копий, компилятор будет неявно создавать * один для вас, а этот неявный будет просто выполнять поэтапное копирование. В этом случае, неявное один будет выглядеть примерно так:

vectstruct& operator=(const vectstruct& rhs) { 
    mymap = rhs.mymap; 
    return *this; 
} 

Для std::map, назначение делает полную копию, он не принимает ссылку, так что в конце кода следует ожидать:

vs2.mymap[7] == 54.321 // to the extent that equality of doubles is a thing 
vs1.mymap[7] == 65.432 

* Бывают случаи, когда компилятор не может создать неявный оператор присваивания, который в основном сводится к вашему объекту, имеющему незакрепляемый элемент. Например, ссылка, или unique_ptr.

1

По умолчанию operator= будет выполнять поэтапную копию, что и есть то, что вы ожидаете. I. e. он будет вызывать operator= для каждого члена данных вашей структуры. И std::map, в свою очередь, реализует operator=, поэтому все будет работать как шарм. Не нужно раздувать ваш код, написав тот же самый оператор самостоятельно.

Смежные вопросы