Възможно ли е да се използва std::map в C++ с клас без оператор за копиране?

Използвам клас (обект), който няма оператор за копиране: той по принцип не може да бъде копиран в момента. имам

std::map<int,Object> objects

променлива, която изброява обекти с int идентификатор. Как мога да добавя обект към тази карта, без да се налага да използвам оператори за копиране? опитах

objects.insert(std::pair<0,Object()>);

но това няма да се компилира. Просто бих искал да създам моя обект първоначално вътре в картата, като използвам конструктора по подразбиране, но като пиша

objects[0]; се проваля... Благодаря :)


person Tuxer    schedule 03.06.2011    source източник
comment
std::map трябва да съхранява някаква стойност. Ако не е копие на Object, може би указател към Object, ако приемем, че Object няма да изчезне.   -  person chrisaycock    schedule 03.06.2011


Отговори (3)


В C++03 обектите, които се съхраняват в STL контейнери, трябва да могат да се копират. Това е така, защото std::allocator на STL контейнер всъщност използва версията за разположение на оператора new, за да копира конструкцията на обектите в предварително разпределени блокове памет и това изисква съществуването на конструктор за копиране, който да копира действителното копие на обекта, който искате за добавяне към контейнера в адреса на паметта, който е бил предварително разпределен от разпределителя на контейнера. Така че единствената ви възможност би била да съхранявате указатели към вашите обекти, а не самите обекти. Следователно можете да направите следното:

std::map<int, std::shared_ptr<Object> > objects;
objects.insert(std::pair<int, std::shared_ptr<Object> >(0, new Object());
person Jason    schedule 03.06.2011
comment
Бих дал положителен глас - ако използвате интелигентни указатели. Кодът за ръчно изтриване е лошо. - person Puppy; 03.06.2011
comment
Е, това направих. Благодаря ви много, работи перфектно. - person Tuxer; 03.06.2011

Не в C++03. Как ще получите обекта от мястото, където е сега, в картата без конструктор за копиране?

В C++0x тогава можете да се преместите в картата и на теория идеално напред, за да конструирате такава на място от други аргументи.

Редактиране: Вие можете да го размените, ако може да се разменя, и можете да го конструирате по подразбиране на място с помощта на operator[].

std::map<int, Object> objmap;
objmap[2]; // Default-constructs an Object in-place
std::swap(objmap[2], Object()); // Swaps it into the map.
person Puppy    schedule 03.06.2011
comment
Това би било идеалното решение, но objmap[2] просто няма да се компилира: /usr/include/c++/4.4/bits/stl_pair.h:84: error: no matching function for call to ‘Object::Object(const Object&)’ - person Tuxer; 03.06.2011

Тъй като вашият обект не може да се конструира чрез копиране, можете да създадете вашата карта, съдържаща shared_ptr:

std::map<int,shared_ptr< Object > >

Това се грижи за унищожаването на обекти.

person BЈовић    schedule 03.06.2011