2015-11-27 3 views
0

Я хочу структуру, которая имеет unordered_map в качестве члена.
Я также не хочу набирать тип все время, поэтому я typedef.C++ - добавление hashmap к структуре

typedef std::unordered_map<std::string, int> HM; 
struct A { 
    HM myHm; 
} 

A *myA = new A(); 
HM hashmap = new HM(); // empty hashmap 
hashmap["1"] = 1; 
myA->myHm = hashmap; 

Конечно, это неверно.

Я вижу примеры людей делают std::unordered_map<std::string, int> HM;
, а затем сразу HM["1"] = 1;

Прежде всего, я привык к Java, где std::unordered_map<std::string, int> HM; просто тип, и если я хочу, чтобы добавить материал к нему, мне нужно для его создания с помощью ().

Кажется, что в C++ он создается в момент, когда я пишу std::unordered_map<std::string, int> HM;. Может ли кто-нибудь рассказать об этом?

Во-вторых, каков правильный способ делать то, что я хочу?

+0

Этот код компилирует и делает то, что вы ожидаете (ну, если вы поместите код внутри функции, которая будет). –

+0

'A mA; HM hashmap; 'достаточны и предпочтительны в C++ для создания полнофункциональных объектов. Нет 'new' означает отсутствие утечек памяти (обычно). Также вы создаете хэш-карту как локальную переменную, а затем копируете ее в хэш-карту в своей структуре. Почему бы просто не использовать это прямо? –

+0

@JamesPicone Я получаю 'преобразование из 'HM *' в нескалярный тип 'HM' request', когда я назначаю' HM() '' HM hashmap'. – pushkin

ответ

4

В C++ вы обычно не пишу:

HM hashmap = HM(); 

Это потому, что вы там делаете, чтобы создать анонимный временный с HM() (конструктор по умолчанию), а затем назначить его на другой называется hashmap , Вместо этого, вы можете просто сделать это:

HM hashmap; 

Это будет одинаково по умолчанию-построить хэш-карту, и избегает любого потенциального ненужного назначения или двойного строительства.

Еще одна проблема с вашим существующим кодом заключается в том, что вы используете new и сохраняете результат в «необработанном» указателе, но никогда не вызываете на него delete. Вместо этого, вы можете пропустить с помощью new в целом, и избежать дублирования, например:

A myA; // contains HM 
myA.myHm["1"] = 1; 

Это делает все, что нужно в минимальном количестве шагов.

0

Способ мышления о том, что может помочь, - подумать обо всех переменных в C++ как о «типах значений», в C# lingo (я не знаю, что такое соответствующий термин Java).

Это Java совершенно законно:

int foo; 
foo = 2; 
foo *= 17 

, потому что «Foo» это просто значение, она живет полностью в стеке и не должны быть выделены.

В Java, когда вы объявляете переменную сложного типа (скажем, HashMap), она не живет в стеке, и она должна быть выделена. В C++, когда вы объявляете переменную сложного типа, это именно то, что вы получаете, и оно живет в стеке. Если вам нужен ссылочный тип, вы должны явно запросить его.

Термин для поиска - это «автоматические переменные». Переменные, объявленные внутри функции, являются «автоматическими переменными», они имеют свои конструкторы, которые вызываются, когда выполнение переходит к их объявлению, и они вызывают их деструкторы, когда их область остается. Here's ссылка на соответствующую страницу Википедии.

Это действительно полезное поведение, и оно лежит за общей идиомой C++ под названием RAII.

Если вы хотите вызвать конструктор типа не по умолчанию, вы можете просто добавить скобки:

SomeType foo(p1, p2); 

Это требует SomeType::SomeType(p1, p2) построить Foo.

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