Manchmal möchte ich die Konstruktion von Objekten, die eine Klasse besitzt, an eine separate Funktion delegieren. Etwas wie
Vertex* new_vertex(const Options& options) {
// do stuff...
return new Vertex(...);
}
wobei die Funktion nur innerhalb einer Klasse verwendet werden soll, die die besitzt Vertex
. Es ist klar, dass diese Funktion zu Verwirrung führen kann, daher möchte ich sie so klar wie möglich machen. Gibt es eine Namenskonvention für solche Funktionen?
c++
coding-standards
Schaf
quelle
quelle
// TODO: Fix allocation of raw pointer.
unique_ptr
indem sie seinerelease()
Funktion aufrufen , und verwenden die rohen Zeiger wie auf die alte Weise.// FIXME: Allocation of raw pointer
?new_vertex
damit ich weiß, dass das Objekt neu geprägt wurde. Man könnte esCreate_new_vertex
als besonders klar bezeichnen. Was die Idee betrifft, dass Sie den Heap-Speicher nicht ohne intelligente Zeiger verwalten sollten, haben Sie nie die Wahrheit darin gesehen. Wenn Sie den Heap-Speicher ohne sie nicht verwalten können, haben Sie auch kein Geschäft damit, den Heap-Speicher mit ihnen zu verwalten!Antworten:
Rückgabe a
unique_ptr
:Es kann immer nur einen geben
unique_ptr
, der auf ein bestimmtes Objekt zeigt (es sei denn, Sie missbrauchen es, indem Sie es auf einVertex*
und zurück werfen ). Sie können niemals eine kopierenunique_ptr
, sondern nur verschieben. Wenn aunique_ptr
zerstört wird (und nicht entfernt wurde), ist es sogardelete
das Objekt für Sie.make_unique
erstellt ein neuesVertex
und hüllt es in einunique_ptr
; Die Argumente, an die Sie übergeben,make_unique
sind die Argumente, die an den Konstruktor übergeben werden.quelle
unique_ptr
dies. Wenn es aus irgendeinem Grund ein Name sein muss, dann denke ich nicht, aber warum muss es ein Name sein?std::make_unique
? Das ist unnötig ausführlich und fehleranfällig ...Nein, es gibt keinen "Standardweg" (aber es gibt eine API-Entwurfsrichtlinie, die derzeit als "Best Practice" gilt).
Aufgrund dieser Mehrdeutigkeit ("Was möchte eine Funktion, die einen Zeiger zurückgibt, von mir?") Wird es derzeit als bewährte Methode angesehen, die Lebensdauer- und Eigentumsrichtlinie über den Rückgabetyp festzulegen:
<vertex pointer type>
kann seinstd::unique_ptr
("new_vertex besitzt den Zeiger nicht") oderstd::shared_ptr
("Clientcode besitzt den Zeiger nicht") oder etwas anderes, das eine klar definierte Besitzersemantik aufweist (z. B.Vertex const * const
würde dem Clientcode anzeigen ", lesen Sie den Adresse und Werte, aber weder ändern noch den Zeiger löschen ").Im Allgemeinen sollten Sie keinen rohen Zeiger zurückgeben (in einigen Fällen schlägt "Praktikabilität die Reinheit").
TLDR : Es gibt eine bewährte Methode ( ja ), aber keine Standardmethode (in der Sprache).
Bearbeiten :
Wenn die Klasse den Vertex besitzt, würde ich ihn so schreiben:
quelle
Ja, es gibt Dutzende von "Standards"
Die empfohlene Antwort
unique_ptr
ist wahrscheinlich die beste Antwort, aber wenn Sie sich rohe Zeiger ansehen, hat jeder seinen eigenen Standard entwickelt.Im allgemeinen Funktion mit dem Namen
create_____
odernew______
oderalloc_____
neigt dazu , ein neues Objekt zu implizieren.jedoch
Bedenken Sie, dass Sie Verhaltensweisen mischen. Es ist Ihnen eigentlich egal, ob dies eine neue Instanz eines Objekts ist oder nicht. Was Sie interessiert, ist, ob der Anrufer für die Zerstörung des Objekts verantwortlich ist oder nicht. Es gibt viele APIs, die die Verantwortung für ein vorhandenes Objekt übertragen, und diese Funktionen benötigen ein übereinstimmendes Namensschema. Vielleicht
give______
.Wenn Sie bereit sind, sich ein wenig von C ++ zu entfernen ...
Wenn Sie bereit sind, Objective-C als C ++ ähnlich genug zu betrachten, um eine Antwortquelle zu finden, gibt es in dieser Sprache tatsächlich eine echte Antwort. Objective-C verwaltet die Lebensdauer von Objekten mithilfe von Referenzzählern. Sie brauchten eine Möglichkeit zu beschreiben, ob Ihnen die Verantwortung für ein Objekt übertragen wurde, oder lediglich einen Verweis auf ein vorhandenes Objekt. Wenn Sie die Antwort falsch verstehen, erhalten Sie die Ref-Zählungen falsch und verlieren Objekte. Dementsprechend haben sie eine Regel aufgestellt: Jedes Objekt, das Sie zurückgeben, gehört einer anderen Person (Sie müssen also die Ref-Anzahl selbst erhöhen und verringern), mit Ausnahme von Erstellungsaufrufen, die einen bereits inkrementierten Zeiger an Sie übergeben (Sie müssen nur dekrementieren). Diese Aufrufe wurden durch den Methodennamen identifiziert. Methoden beginnend mit
alloc
new
copy
odermutableCopy
hat immer ein neues Objekt zurückgegeben. Dort wurde der Standard also von der Sprache durchgesetzt.quelle