A veces quiero delegar la construcción de objetos que posee una clase a una función separada. Algo como
Vertex* new_vertex(const Options& options) {
// do stuff...
return new Vertex(...);
}
donde la función solo está destinada a ser utilizada dentro de una clase que posee el Vertex
. Claramente, esta función puede causar cierta confusión de pérdida de memoria, por lo que quiero dejarlo lo más claro posible. ¿Existe una convención de nomenclatura para tales funciones?
c++
coding-standards
Shep
fuente
fuente
// TODO: Fix allocation of raw pointer.
unique_ptr
llamando a surelease()
función, y usar los punteros en bruto como en las viejas formas.// FIXME: Allocation of raw pointer
?new_vertex
así que sé que el objeto está recién acuñado. Podrías llamarloCreate_new_vertex
para ser más claro. En cuanto a la idea de que no se debe gestionar la memoria heap sin punteros inteligentes, nunca había visto la verdad porque - de hecho, si usted no puede manejar la pila de memoria y sin ellos, no tienes negocio la gestión de memoria del montón con ellos, ya sea!Respuestas:
Devolver a
unique_ptr
:Solo puede haber uno que
unique_ptr
apunte a un objeto determinado (a menos que lo maltrate arrojándolo haciaVertex*
atrás y hacia atrás, de todos modos). Nunca puedes copiar ununique_ptr
, solo moverlo. Cuando aunique_ptr
se destruye (y no se ha eliminado), inclusodelete
es el objeto para usted.make_unique
crea un nuevoVertex
y lo envuelve en ununique_ptr
; los argumentos que pasamake_unique
son los argumentos que pasa al constructor.fuente
unique_ptr
haga eso. Si tiene que ser un nombre por alguna razón, entonces supongo que no, pero ¿por qué tiene que ser un nombre?std::make_unique
? Eso es innecesariamente detallado y propenso a errores ...No, no existe una "forma estándar" (pero hay una política de diseño de API actualmente considerada "mejor práctica").
Debido a esta ambigüedad ("¿qué quiere que haga una función que devuelve un puntero?"), Actualmente se considera la mejor práctica imponer la política de vida y propiedad, a través del tipo de devolución:
<vertex pointer type>
puede serstd::unique_ptr
("new_vertex no posee el puntero"), ostd::shared_ptr
("el código del cliente no posee el puntero"), o algo más, que tenga una semántica de propiedad claramente definida (por ejemplo,Vertex const * const
indicaría al código del cliente "leer el dirección y valores, pero no cambie ninguno / no elimine el puntero ").En general, no debe devolver un puntero sin formato (pero en algunos casos, "la practicidad es mejor que la pureza").
TLDR : hay una mejor práctica ( sí ), pero no una forma estándar (en el idioma).
Editar :
Si la clase posee el Vértice, lo escribiría así:
fuente
Sí, hay docenas de "estándares" sobre esto
La respuesta recomendada
unique_ptr
es probablemente la mejor respuesta, pero si está buscando punteros en bruto, todos han desarrollado su propio estándar.En términos generales las funciones nombradas
create_____
onew______
oalloc_____
tienden a implicar un nuevo objeto.sin embargo
Considera que estás mezclando comportamientos. Realmente no le importa si esta es una nueva instancia de un objeto o no. Lo que le importa es si la persona que llama es responsable de destruir el objeto o no. Hay muchas API que transfieren la responsabilidad de un objeto existente, y esas funciones necesitarán un esquema de nomenclatura coincidente. Tal vez
give______
.Si está dispuesto a alejarse un poco de C ++ ...
Si está dispuesto a considerar que Objective-C es lo suficientemente similar a C ++ como fuente de respuesta, en realidad hay una respuesta real en ese lenguaje. Objective-C gestiona la vida útil de los objetos utilizando recuentos de referencia. Necesitaban una manera de describir si se le estaba dando la responsabilidad de un objeto, o simplemente una referencia a un objeto existente. Si obtienes la respuesta incorrecta, obtienes los recuentos de referencia incorrectos y pierdes objetos. En consecuencia, establecieron una regla: cada objeto que devuelve es propiedad de otra persona (por lo que debe aumentar y disminuir el recuento de referencia usted mismo), excepto las llamadas de creación que le pasan un puntero ya incrementado (solo tiene que disminuir). Estas llamadas fueron identificadas por el nombre del método. Métodos que comienzan con
alloc
new
copy
omutableCopy
siempre devuelve un nuevo objeto. Entonces, el estándar hizo cumplir el estándar.fuente