vector hinzufügen ohne objekt zu kopieren (ggf. refcount++)
-
laut http://en.cppreference.com/w/cpp/memory/unique_ptr muss ich <memory> einbinden...
dann müsste ich das doch so definieren:
typedef std::vector<std::unique_ptr<TElement>> TElementList;aber ich bekomme die Fehlermeldung
‘unique_ptr’ is not a member of ‘std’was mache ich falsch?
-
Vermutlich musst du bei deinem Compiler erst den C++11 Modus einschalten.
-
nutze den g++ (4.4.3) unter linux
http://gcc.gnu.org/projects/cxx0x.html
Important: GCC's support for C++11 is still experimental.trotzdem hab ichs mal probiert:
g++ -Wall -std=c++11 platine.cpp -o platine `pkg-config --cflags gtk+-2.0` `pkg-config --libs gtk+-2.0`cc1plus: error: unrecognized command line option "-std=c++11"
in der man-page finde ich den 11er nicht nur 0x
gibts nix vergleichbares zu unique_ptr im c++ standard?
-
C++0x = C++11. Also stimmt -std=c++0x schon.
-
jetzt findet er es zumindest mal...
aber scheinbar ändert sich da auch mein aufruf...
Fehlermeldung:
error: no matching function for call to ‘std::vector<std::unique_ptr<TConnection, std::default_delete<TConnection> >, std::allocator<std::unique_ptr<TConnection, std::default_delete<TConnection> > > >::push_back(TConnection&)’
/usr/include/c++/4.4/bits/stl_vector.h:733: note: candidates are: void std::vector<_Tp, _Alloc>::push_back(const _Tp&) [with _Tp = std::unique_ptr<TConnection, std::default_delete<TConnection> >, _Alloc = std::allocator<std::unique_ptr<TConnection, std::default_delete<TConnection> > >]
/usr/include/c++/4.4/bits/stl_vector.h:746: note: void std::vector<_Tp, _Alloc>::push_back(_Tp&&) [with _Tp = std::unique_ptr<TConnection, std::default_delete<TConnection> >, _Alloc = std::allocator<std::unique_ptr<TConnection, std::default_delete<TConnection> > >]code:
TElement::TElement(...) { ... TConnection c(fPlatine,this,id,s); Connections.push_back(c); //diese zeile wird bemängelt}
-
Du hast ja jetzt auch keine Values mehr in deinem vector, sondern unique_ptr!
-
über gebe ich dann die Speicheradresse??
also push_back(&c)?
ggf. mit cast auf unique pointer oder wie läuft das dann?
wie bekomme ich mein Objekt wieder raus und wie ist das mit der Speicherfreigabe?
-
Du musst die Objekte dynamisch anlegen. Freigegeben werden sie automatisch, da es sich um einen Smart-Pointer handelt.
std::unique_ptr<TConnection> c(new TConnection(fPlatine,this,id,s)); Connections.push_back(c);
-
mhm, kann ich da einfach per list[i] auf die TConnections zugreifen?
habe überlegt, obs nicht sinnvoller wäre die ganze pointer-verarbeitung aus dem constructor rauszuverlagern (init-prozedure), die ich auf das listen-element ausführe.
Pseudocode:
std::vector<TConnection> TConnectionList; TConnectionList clist; TConnection c(); clist.push_back(c); clist[clist.size()-1].init(...)
-
ich lasse jetzt die Berechnungen das übergeordnete TElement machen und kann somit auf die Pointer verzichten. Ich denke das ist die sinnvollste und stabilste Variante.
Danke trotzdem an alle, die mitgeholfen haben
-
mhm, klappt doch nicht ganz ohne die pointer,
probiere schon eine Weile rum, aber komme nicht wirklich weiter mit dem unique_ptr...
typedef std::vector<std::unique_ptr<TElement>> pElementList; pElementList pElements; unique_ptr<TElement> pE(new TElement()); pE->InitElement(this,Template,left,top,4,4); pElements.push_back(pE);bei der letzten Zeile wirft mir der cimpiler eine 10-seitige Fehlermeldung um die Ohren aus der ich nicht wirklich was herausnehmen kann...
In file included from /usr/include/c++/4.4/i486-linux-gnu/bits/c++allocator.h:34,
from /usr/include/c++/4.4/bits/allocator.h:48,
from /usr/include/c++/4.4/string:43,
from /usr/include/c++/4.4/bits/locale_classes.h:42,
from /usr/include/c++/4.4/bits/ios_base.h:43,
from /usr/include/c++/4.4/ios:43,
from /usr/include/c++/4.4/ostream:40,
from /usr/include/c++/4.4/iostream:40,
from platine.h:1,
from platine.cpp:1:
/usr/include/c++/4.4/bits/unique_ptr.h: In member function ‘void __gnu_cxx::new_allocator<_Tp>::construct(_Tp*, const _Tp&) [with _Tp = std::unique_ptr<TElement, std::default_delete<TElement> >]’:
/usr/include/c++/4.4/bits/stl_vector.h:737: instantiated from ‘void std::vector<_Tp, _Alloc>::push_back(const _Tp&) [with _Tp = std::unique_ptr<TElement, std::default_delete<TElement> >, _Alloc = std::allocator<std::unique_ptr<TElement, std::default_delete<TElement> > >]’
platine.cpp:499: instantiated from here
/usr/include/c++/4.4/bits/unique_ptr.h:214: error: deleted function ‘std::unique_ptr<_Tp, _Tp_Deleter>::unique_ptr(const std::unique_ptr<_Tp, _Tp_Deleter>&) [with _Tp = TElement, _Tp_Deleter = std::default_delete<TElement>]’
/usr/include/c++/4.4/ext/new_allocator.h:105: error: used here
In file included from /usr/include/c++/4.4/vector:69,
from platine.h:3,
from platine.cpp:1:
/usr/include/c++/4.4/bits/unique_ptr.h: In member function ‘void std::vector<_Tp, _Alloc>::_M_insert_aux(__gnu_cxx::__normal_iterator<typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::pointer, std::vector<_Tp, _Alloc> >, _Args&& ...) [with _Args = const std::unique_ptr<TElement, std::default_delete<TElement> >&, _Tp = std::unique_ptr<TElement, std::default_delete<TElement> >, _Alloc = std::allocator<std::unique_ptr<TElement, std::default_delete<TElement> > >]’:
/usr/include/c++/4.4/bits/stl_vector.h:741: instantiated from ‘void std::vector<_Tp, _Alloc>::push_back(const _Tp&) [with _Tp = std::unique_ptr<TElement, std::default_delete<TElement> >, _Alloc = std::allocator<std::unique_ptr<TElement, std::default_delete<TElement> > >]’
platine.cpp:499: instantiated from here
/usr/include/c++/4.4/bits/unique_ptr.h:214: error: deleted function ‘std::unique_ptr<_Tp, _Tp_Deleter>::unique_ptr(const std::unique_ptr<_Tp, _Tp_Deleter>&) [with _Tp = TElement, _Tp_Deleter = std::default_delete<TElement>]’
/usr/include/c++/4.4/bits/vector.tcc:314: error: used here
-
Es muss
pElements.push_back(std::move(pE));heißen. Dies hat auch Nexus falsch gemacht.
-
ok, danke
kann ich da nicht auf unique_ptr verzichten und std::move beim normalen vector anwenden (damit keine Kopie erstellt wird)?
TElement e; fElements.push_back(std::move(e));der compiler frisst es zumindest

-
Wenn der Default-Move-Ctor das richtige tut, oder du deinen eigenen hast, schon.
-
Was du auch noch machen könntest, wäre emplace_back zu verwenden. Dem übergibt man die Konstruktor-Argumente und das Element wird ohne Kopie direkt im vector erstellt.
-
314159265358979 schrieb:
Wenn der Default-Move-Ctor das richtige tut, oder du deinen eigenen hast, schon.
ich habe einen leeren constructor, da ich die Klasse erst mit der InitElement initialisiere...
ich weis ja nicht, ob std::move das tut, was ich will...er soll das erstellte objekt in den Vector "moven" (also nicht kopieren, sondern verschieben)
-
Ein neues Objekt muss bei push_back auf jeden Fall erstellt werden. Das mit InitElement vergiss mal wieder, das ist Schwachsinn. Member werden im Ctor initialisiert. Ich würde wohl die Variante mit unique_ptr nehmen.
-
mhm...
muss ich auf noch irgendwas achten, oder kann ich das einfach so verwenden:typedef std::vector<std::unique_ptr<TElement>> pElementList; pElementList pElements; unique_ptr<TElement> pE(new TElement()); pE->InitElement(this,Template,left,top,4,4);//init-code in constructor verlagern pElements.push_back(std::move(pE));stimmt der zugriff? freigegeben wird das TElement ja, wenn die liste zerstört wird, oder? bzw. wenn ich erase aufrufe...kann ich irgendwie elemente ohne iterator löschen? also per index-zugriff (z.b. remove(4) soll das 5.element löschen)?
-
Stimmt so, ja. Ein Element an einer bestimmten Position im vector kannst du löschen durch:
vec.erase(vec.begin() + n);Bei vector könnte sowas jedoch langsam sein, da hier alle Elemente hinter dem gelöschten um eine Stelle vorgeschoben werden müssen.
-
314159265358979 schrieb:
Bei vector könnte sowas jedoch langsam sein, da hier alle Elemente hinter dem gelöschten um eine Stelle vorgeschoben werden müssen.
welche Alternativen gäbe es denn? prinzipiell brauche ich ja ein dynamisches array mit Klassen-Elementen.