make_shared Problem/Frage
-
Hallo zusammen,
ich bin gerade dabei mir die Neuerungen von C++11 anzuschauen und anzuwenden. Allerdings bin ich schon auf ein Problem gestoßen und weiß leider nicht weiter.
Ich lege mir ein neues "_ns2__login" Objekt an. Klappt soweit auch. In dieser Klasse ist nun eine Eigenschaft mit dem Namen "ns2__LoginRequest".
auto loginRequest = make_shared<_ns2__login>(); loginRequest->ns2__LoginRequest = make_shared<_ns2__LoginRequest>();Diese versuche ich ebenfalls mit make_shared zu instanziieren. Leider kommt aber die Fehlermeldung:
"Fehler 1 error C2440: '=': 'std::tr1::shared_ptr<_Ty>' kann nicht in 'BasicService::_ns2__LoginRequest *' konvertiert werden"Ich begreife natürlich den Fehler aber werden solche Objekte nicht mehr mit make_shared erstellt oder wie geht man hier vor? Immerhin bekomme ich ja einen shared_ptr zurück.
-
Wem auch immer diese Benennung zu verdanken ist, gehört mal gehörig eine verpasst.

Zu deinem Problem: Du willst einem T* einen shared_ptr<T> zuweisen, das kann ja nicht funktionieren. Und der neue tolle fancy Smartpointer aus C++11 ist eher unique_ptr, nicht shared_ptr.
-
Ok, bevor man mich für komplett dämlich erklärt....Die Benamung kommt von Daimler und das mit den ganze __ kommt von gsoap;-) Ist also nicht auf meinem Mist gewachsen;-)
Und nun wieder zu dem Problem. Bevor ich mich hier total zum Affen machen... Wie müssten denn dann meine zwei Zeilen Code aussehen;-)?
-
Na ja ns2__LoginRequest müsste ein shared_ptrBasicService::\_ns2\_\_LoginRequest sein.
struct A { struct B { }; std::shared_ptr<B> b; }; int main() { auto a = make_shared<A>(); a->b = make_shared<B>(); }Allerdings fragt sich 1. warum du da überhaupt Pointer brauchst und 2. warum du nicht unique_ptr benutzt. (Achtung, make_unique gibt's nicht, haben sie wohl vergessen (lol, ja, das ist ernst gemeint), sieht dann so aus: std::unique_ptr<T>(new T(...));)
-
secondsun schrieb:
auto loginRequest = make_shared<_ns2__login>(); loginRequest->ns2__LoginRequest = make_shared<_ns2__LoginRequest>();Diese versuche ich ebenfalls mit make_shared zu instanziieren. Leider kommt aber die Fehlermeldung:
"Fehler 1 error C2440: '=': 'std::tr1::shared_ptr<_Ty>' kann nicht in 'BasicService::_ns2__LoginRequest *' konvertiert werden"Ich begreife natürlich den Fehler aber werden solche Objekte nicht mehr mit make_shared erstellt oder wie geht man hier vor?
Immerhin bekomme ich ja einen shared_ptr zurück.Wie geht man vor? Man überlegt sich vorher ein Design und versucht es dann umzusetzen. Es hat aber keiner so richtig einen Überblick über das, was du machen willst.
Es sieht nur auf den ersten Blick so aus, als ob du shared_ptr missbrauchen würdest. Ich habe den Eindruck, als ob dir das Konzept der Besitzverhältnisse in C++ nicht ganz vertraut ist und dass du shared_ptr einfach nur als "poor man's garbage collection" einsetzen willst. Das "shared" in shared_ptr bezieht sich nämlich auf genau das. Mehrere shared_ptr-Instanzen "teilen sich den Besitz" eines anderen dynamisch allozierten Objekts. Du solltest wirklich anfangen, in solchen Besitzverhältnissen zu denken. Mit "Besitz" meint man u.a. die Verantwortung zur Verwaltung und Freigabe dessen, was einer oder mehrere zusammen besitzen. Werden diese Besitzverhältnisse beim Design berücksichtigt, wird auch klar, wann du wo welche Art von Zeiger (wenn überhaupt) verwenden solltest.
T* --> Ein roher Zeiger besitzt nichts. Er kann für "kennt"-Beziehungen verwendet werden. unique_ptr<T> --> Ein unique_ptr ist alleiniger Besitzer einer Resource und gibt sie wieder frei, wenn der unique_ptr zerstört wird. Das ist praktisch für "besteht-aus"-Beziehungen, bei denen du polymorphes Verhalten haben willst oder bei denen das, worauf er zeigt, optional ist oder verzögert erstellt wird. shared_ptr<T> --> Ein shared_ptr kann sich den Besitz mit anderen shared_ptrs teilen. Es gibt sicherlich Situationen, wo so etwas sinnvoll ist. Aber typischerweise kann man einen einzigen "Besitzer" identifizieren und einfach unique_ptr nehmenUnd oft macht es auch viel mehr Sinn, gar keinen Zeiger zu verwenden. Du kannst Objekte ja auch direkt als Subobjekte in andere einbetten oder im automatischen Speicher anlegen. Überleg dir also genau, ob du ein make_shared oder new überhaupt brauchst. Für delete und delete[] gibt es in modernem C++ Code aber wirklich so gut wie keinen Platz mehr. Dafür gibt's die Container aus der Standardbibliothek und eben diese "Schlau-Zeiger".
Übrigens gehören Bezeichner mit "Doppelunterstrichen" zu denen, die reserviert sind. Du darfst sie also nicht verwenden. Gleiches gilt für Bezeichner, die mit einem Unterstrich anfangen und dann mit einem Großbuchstaben weiter gehen, wie z.B. "_Ty". Die Microsoftentwickler haben den Template-Parameter von shared_ptr nicht "_Ty" genannt, weil sie ihn schön finden, sondern weil der C++ Standard den "Normalos" verbietet, solche Namen zu verwenden; denn sonst könnten sie ja einfach
#define _Ty "fucked up"vor die Includes packen und nix geht mehr. Namen mit Doppelunterstrichen gehören auch dazu.