¿Qué significa expresar “Propiedad de los recursos”? ¿Es lo mismo que tener la propiedad de punteros? Por ejemplo, en esta respuesta, se utilizó la expresión “Los POD no pueden expresar la propiedad de punteros o recursos”. Las clases que implican la gestión dinámica de la memoria, ¿expresan la propiedad de punteros o recursos?
¿Qué es la propiedad de los recursos o punteros?
Angew ya no está orgulloso de SO
No creo que exista una definición universalmente aceptada, 100% precisa y siempre aplicable, pero la definición más útil de propiedad que he encontrado en el contexto de C++ (y la programación en general) es responsabilidad de la limpieza. Es decir, un propietario de un recurso es el responsable de la limpieza correcta de ese recurso.
El significado de “recurso” y “limpieza” depende del contexto. Cuando el recurso es memoria asignada dinámicamente a través de new
la limpieza está llamando delete
. Cuando el recurso es un descriptor de archivo, la limpieza lo cierra. Y así.
Es por eso que Plain Old Data no puede expresar propiedad: una clase POD debe tener un destructor no operativo y, por lo tanto, no puede realizar ninguna limpieza automática.
Comparar int *
, std::unique_ptr<int>
y std::shared_ptr<int>
. Todos estos tipos son “un puntero a un int
“. Pero el primero no representa la propiedad: puede hacer lo que quiera con él y puede usarlo felizmente de manera que provoque pérdidas de memoria o dobles liberaciones.
std::unique_ptr<int>
representa la forma más simple de propiedad: dice “Soy el único propietario del recurso (= el recurso asignado dinámicamente int
). Cuando me destruyen, lo limpio correctamente.” Está diseñado para no ofrecer una forma sensata de violar la semántica de propiedad (por ejemplo, no se puede copiar).
std::shared_ptr<int>
representa una forma más compleja de propiedad: “Soy uno de un grupo de amigos que son colectivamente responsables del recurso. El último de nosotros en ser destruido lo limpiará”. Una vez más, hay algunos aros por los que pasar antes de poder violar la semántica.
-
Muchas gracias por una gran respuesta. Tengo algunas preguntas: <1> ¿Qué es un
no-op destructor
? (tu dijiste “… una clase POD debe tener un destructor no operativo…”) <2> ¿Podría dar más detalles o compartir enlaces útiles sobre “Está diseñado para no ofrecer una forma sensata de violar la semántica de propiedad (por ejemplo, no se puede copiar)”.?– Milán
19 oct 2021 a las 16:03
-
@Milan 1) El estándar para eso es destructor trivial: en términos sencillos, no lo proporciona el usuario y no hace nada (todos los miembros y las bases también tienen destructores triviales). 2) Lo siento, nada a la mano. Básicamente, la interfaz de
std::unique_ptr
está diseñado para que tengas que pasar por algunos aros antes de que puedas usarlo mal (pero se puede hacer, por supuesto).– Angew ya no está orgulloso de SO
20 oct 2021 a las 7:14
-
Gracias Angew. Lo siento pero dos cosas más: 1. por estándarquisiste decir esto github.com/estándarese/estándarese ¿derecho? 2. Gracias por aclarar
std::unique_ptr
interfaz. Cada vez que encuentre algunos recursos relevantes para eso, compártalos aquí. ¡Lo agradecería mucho!– Milán
20 oct 2021 a las 18:38
-
@Milan No, no quise decir eso en absoluto. Quise decir “estándar” como “el lenguaje utilizado por el estándar C++”, de manera análoga a la palabra “legalés” como “el lenguaje formal generalmente enrevesado utilizado en licencias o contratos”.
– Angew ya no está orgulloso de SO
21 oct 2021 a las 6:24
Es posible que desee leer sobre RAII, que significa Adquisición de recursos es inicialización.
– MSalters
28 de febrero de 2018 a las 8:39