2 Fragen zur std::map
-
cooky451 schrieb:
Oder du nimmst std::move.

Was nur was bringt, wenn
sf::Imagemovable ist. Entweder durch selbst definierten Move-Konstruktor und -Zuweisungsoperator oder durch einen automatisch generierten, sofern der Compiler es unterstützt und die Big Three nicht definiert wurden.std::move()ist eine gute Sache, aber bis es konsequent eingesetzt werden kann, werden noch einige Jahre ins Land ziehen... :xmas2:
-
Bei "schwergewichtigen" Klassen wie
sf::Imagekann man IMO bedenkenlos zustd::shared_ptrbzw.boost::shared_ptrgreifen, wenn man sich das Leben damit leichter machen kann.
Alsostd::map<std::string, std::shared_ptr<sf::image>>.
Bzw. wenn man unbedingt will kann man auchstd::unique_ptrverwenden.In dem Fall würde ich wohl eher
std::shared_ptrwählen: wieso verbieten dass der "Client-Code" einsf::Imageweiterverwendet, nachdem das Manager-Objekt (CResources) bereits zerstört wurde?Dann kann man weiterhin das Bild erstmal vollständig laden, und erst danach in die
mapeinfügen -> kein Rollback mehr nötig.
Beim kopieren desshared_ptr(Einfügen in die Map) fallen dann 2-3 Interlocked Befehle an, was aber in diesem Fall kaum ins Gewicht fallen wird.
-
Das mit dem shared_ptr hört sich gut an. Allerdings sag mir der Compiler das er std::shared_ptr nicht kennt. Was muss ich dafür installieren/einbinden?
Was ist hier mit Rollback gemeint?
Und was sind Interlocked Befehle?Und noch eine Frage:
Wenn ich sowas schreiben würde:std::vector<CClass*> CClassVec; CClassVec.push_back(&CClass());wie lange lebt CClass im vector?
-
Damit gibst du einen Pointer auf ein temporäres Objekt zurück, das sofort nach dem Befehl zerstört wird. Keine gute Idee.

Für shared_ptr brauchst du <memory>. Ich würde allerdings unique_ptr empfehlen.
-
JJ schrieb:
Und was sind Interlocked Befehle?
Ein shared_ptr hält intern einen (um genau zu sein zwei, aber das ist im Moment nebensächlich) Referenzzähler. Wenn ein shared_ptr kopiert wird, wird der Zähler inkrementiert. Wird ein shared_ptr zerstört, dann wird er dekrementiert. Sobald der Refernzzähler auf 0 geht, wird das Objekt zerstört. Dieses Inkrementieren und Dekrementieren wird über Funktionen gemacht, die threadsicher sind, damit die Referenzzähler immer "richtig" bleiben.
JJ schrieb:
Und noch eine Frage:
Wenn ich sowas schreiben würde:std::vector<CClass*> CClassVec; CClassVec.push_back(&CClass());wie lange lebt CClass im vector?
Ganz einfach: Du holst die Addresse eines temporären Objekts, somit wird das Objekt gleich wieder zerstört und du hast einen ungültigen Zeiger eingefügt.
cooky451 schrieb:
Ich würde allerdings unique_ptr empfehlen.
Das hängt wirklich vom Anwendungsfall ab. Mir gefällt die Idee von hustbaer eigentlich ziemlich gut. Vor allem könnte man im Client-Code auch weak_ptr auf die Objekte halten, was mir auch nützlich erscheint.
-
Hallo nochmal :xmas1: !
Bin grad den Boost::shared_ptr am einbinden und bin dann nach etlichen Fehlermeldungen bei diesem compilierbaren Code gelandet:
#pragma once #include <map> #include <SFML/Graphics.hpp> #include <Boost/shared_ptr.hpp> class CResources { private: std::map<std::string, boost::shared_ptr<sf::Image>> Images; const boost::shared_ptr<sf::Image> addImage(std::string Filename) { boost::shared_ptr<sf::Image> newImage(new sf::Image()); #pragma region Errormessages if (!newImage.get()->LoadFromFile(Filename)) { std::cerr << "const CResources::addImage(std::string Filename)\n"; std::cerr << "I/O error while reading file. File may not exist:\n \"" << Filename << "\"" << std::endl; } #pragma endregion std::pair<std::string, boost::shared_ptr<sf::Image>> newInsert(Filename, newImage); return Images.insert(newInsert).first->second; } public: const boost::shared_ptr<sf::Image> getImage(std::string Filename) { if(Images.find(Filename) != Images.end()) { return Images.find(Filename)->second; } else { return addImage(Filename); } } };Ist das ok so? Verwende ich die Container sinngemäß? Sollte ich die namespaces weglassen? (also using namespace std etc. einfügen) ich finde das sieht einwenig unübersichtlich aus im moment. Für ein paar gute Codeschnipsel wäre ich dankbar :).
Danke für eure Mühe!
Bisher bin ich gut vorwärts gekommen...
-
Warum nutzt du nicht std::shared_ptr? (Oder unique_...^^)
Ansonsten:
- Hilft dir das #pragma region wirklich? Das sind doch nur 4 Zeilen.
- Zeile 20: "auto NewInsert = std::make_pair(Filename, NewImage);" Oder gleich die Zeile weg und insert(std::make_pair(..));
- Zeile 25: Warum durchsuchst du die map zwei mal? Das ist doch eine ziemliche Performanceverschwendung. Ich denke mal nicht, dass das optimiert wird. Wie wäre es mit:auto found = Images.find(Filename); if (found != std::end(Images)) ..
-
Das #pragma region hab ich überall bei den Fehlermeldungen, dann steht da immer eine Zeile "Errormessages", statt eine fetter Block mit fehlerbehandlungsroutinen.
Warum ich boost::shared_ptr statt std::shared_ptr verwende?
Ich habe versucht <memory> zu includen ging dann immernoch nicht, dann hab ich mir einfach boost gezogen, das brauche ich wahrscheinlich sowieso in naher Zukunft :).auto frisst mein complier nicht.
Error 1 error C4430: missing type specifier - int assumed. Note: C++ does not support default-int Error 2 error C2440: 'initializing' : cannot convert from 'std::_Tree<_Traits>::iterator' to 'int' Error 3 error C4430: missing type specifier - int assumed. Note: C++ does not support default-int Error 4 error C2440: 'initializing' : cannot convert from 'std::_Tree<_Traits>::iterator' to 'int'Ich hab VS 2008, liegt das daran?
Ich glaub deshalb habe ich auch das std::shared_ptr nicht...Hab stattdessen das ganze ausgeschrieben:
std::map<std::string, boost::shared_ptr<sf::Image>>::iterator Found(Images.find(Filename)); if(Found != Images.end()) {
-
JJ schrieb:
auto frisst mein complier nicht.
[...]
Ich hab VS 2008, liegt das daran?
Ich glaub deshalb habe ich auch das std::shared_ptr nicht...Ja liegt daran und du glaubst richtig

Wobei shared_ptr im "Feature Pack" für VS 2008 drinnen ist, bzw. genau so im SP1.
Allerdings nur mit Visual Studio Versionen >= Standard (d.h. NICHT Express).Aber nimm ruhig Boost, dort ist shared_ptr gewachsen, und die funktionieren zu 99% gleich wie die in std::.
-
Der Boost ptr dürfte zwar wirklich keinen Unterschied machen, aber warum nutzt du nicht gleich VS 2010 und nutzt dann auto etc.?
Die C++11 Teile die Microsoft da schon implementiert hat sind doch viel zu hüsch um auf sie zu verzichten.