C ++ Smart Pointer const Korrektheit
Ich habe ein paar Container in einer Klasse, zum Beispiel vector oder eine map, die enthalten
shared_ptr - Objekte Leben auf dem heap.
Beispielsweise
template <typename T>
class MyExample
{
public:
private:
vector<tr1::shared_ptr<T> > vec;
map<tr1::shared_ptr<T> , int> h;
};
Ich will eine öffentliche Schnittstelle dieser Klasse, manchmal gibt shared_ptrs
const-Objekte (über shared_ptr<const T>
) und manchmal shared_ptr<T>
wo
Ich lasse die Anrufer zu mutieren die Objekte. Ich will logische const-correctness ist, also, wenn ich mark
eine Methode als const, kann es nicht ändern, die Objekte auf dem heap.
Fragen:
1) ich bin verwirrt durch die Austauschbarkeit von tr1::shared_ptr<const T>
und tr1::shared_ptr<T>
.
Wenn sich jemand übergibt eine shared_ptr<const T>
shared_ptr in die Klasse, Speichere ich es als shared_ptr<T>
oder shared_ptr<const T>
im inneren der vector und map oder muss ich die Karte wechseln, Vektor-Typen (z.B. insert_elemeent(shared_ptr<const T>
obj) ?
2) Ist es besser zu instanziieren-Klassen wie folgt: MyExample<const int>
? Das scheint
zu restriktiv sind, da kann ich nie wieder ein shared_ptr<int>
?
InformationsquelleAutor der Frage user231536 | 2010-01-17
Du musst angemeldet sein, um einen Kommentar abzugeben.
shared_ptr<T>
undshared_ptr<const T>
sind nicht austauschbar sind. Es geht ein Weg -shared_ptr<T>
ist konvertierbar zushared_ptr<const T>
aber nicht Umgekehrt.Beobachten:
kompilieren über
Können Sie auch überladen einer Funktion basierend auf einem constness. Sie kombinieren können, um diese beiden Tatsachen zu tun, was Sie wollen.
Als für Ihre zweite Frage,
MyExample<int>
wahrscheinlich mehr Sinn macht, alsMyExample<const int>
.InformationsquelleAutor der Antwort Terry Mahaffey
Ich würde vorschlagen, die folgenden methotology:
Dieser sorgt für const-Korrektheit. Wie Sie sehen, das add () - Methode nicht verwenden, <const T> aber <T> denn Sie wollen die Klasse zum speichern von Ts nicht const Ts. Aber, wenn der Zugriff const, kehren Sie <const T> ist das kein problem, da shared_ptr<T> kann leicht umgewandelt werden, um shared_ptr<const T>. Und sice sowohl get () - Methoden liefern Kopien der shared_ptr in Ihrem internen Speicher der Anrufer kann nicht versehentlich ändern Sie das Objekt Ihrer internen Zeiger zeigen. Dies ist vergleichbar zu den nicht-smart-pointer-Variante:
InformationsquelleAutor der Antwort mmmmmmmm
Wenn sich jemand übergibt Sie eine
shared_ptr<const T>
sollten Sie nie in der Lage sein zu ändernT
. Es ist natürlich technisch möglich, die Besetzung derconst T
nur einT
aber das bricht der Absicht, dass dieT
const
. Also, wenn Sie wollen, dass die Leute in der Lage sein, um das hinzufügen von Objekten zu Ihrer Klasse, dass Sie sollten geben Sieshared_ptr<T>
und keineshared_ptr<const T>
. Wenn Sie wieder Dinge aus Ihrer Klasse wollen Sie nicht geändert, das ist, wenn Sie verwendenshared_ptr<const T>
.shared_ptr<T>
können automatisch umgesetzt werden (ohne expliziten cast) zu einemshared_ptr<const T>
aber nicht die andere Weise herum. Es kann Ihnen helfen (und Sie sollten es trotzdem tun), um liberale Verwendung vonconst
Methoden. Wenn Sie eine Klasse definieren, Methodeconst
der compiler wird nicht zulassen, Sie ändern Ihre Daten-member oder Rückgabe etwas, außer einemconst T
. Daher ist die Verwendung dieser Methoden wird Ihnen helfen, sicherzustellen, dass Sie nicht etwas vergessen, und wird Benutzern helfen, Eure Klasse zu verstehen, was die Absicht der Methode ist. (Beispiel:virtual shared_ptr<const T> myGetSharedPtr(int index) const;
)Sind Sie richtig auf Ihre zweite Aussage, die Sie wahrscheinlich nicht wollen, instanziieren Sie die Klasse als
<const T>
da Sie nie in der Lage, ändern Sie IhreT
s.InformationsquelleAutor der Antwort SoapBox
einer Sache zu erkennen ist, dass:
tr1::shared_ptr<const T>
ist, imitiert die Funktionalität derT const *
nämlich das, was es zeigt, ist const, aber der Zeiger selbst nicht.So können Sie einen neuen Wert zuweisen, um Ihre freigegebenen Zeiger, aber ich würde erwarten, dass Sie wäre nicht in der Lage zu verwenden, die aufgelöst
shared_ptr
als l-Wert.InformationsquelleAutor der Antwort Evan Teran