Pregunta ¿Para qué es el constructor de alias de shared_ptr?


En esta página (http://www.cplusplus.com/reference/memory/shared_ptr/), párrafo 5, dice:

Además, los objetos shared_ptr pueden compartir la propiedad sobre un puntero mientras que al mismo tiempo apuntan a otro objeto. Esta capacidad se conoce como aliasing (ver constructores), y se usa comúnmente para apuntar a los objetos miembros mientras son dueños del objeto al que pertenecen. Debido a esto, un shared_ptr puede estar relacionado con dos punteros:

  • Un puntero almacenado, que es el puntero al que apunta, y el que desreferencia con el operador *.

  • Un puntero de propiedad (posiblemente compartido), que es el puntero que el grupo de propiedad se encarga de eliminar en algún momento, y para el cual cuenta como un uso.

En general, el puntero almacenado y el puntero propio se refieren al mismo objeto, pero los objetos alias shared_ptr (aquellos construidos con el constructor de alias y sus copias) pueden referirse a diferentes objetos.

Luego leo esta página (http://www.cplusplus.com/reference/memory/shared_ptr/shared_ptr/) sobre el constructor de aliasing de shared_ptr. Pero todavía creo que este comportamiento de "aliasing" es confuso. ¿Por qué está aquí? ¿Para qué sirve? ¿En qué situación me gustaría esta característica?


32
2017-11-24 16:22


origen


Respuestas:


Ejemplo simple:

struct Bar { 
    // some data that we want to point to
};

struct Foo {
    Bar bar;
};

shared_ptr<Foo> f = make_shared<Foo>(some, args, here);
shared_ptr<Bar> specific_data(f, &f->bar);

// ref count of the object pointed to by f is 2
f.reset();

// the Foo still exists (ref cnt == 1)
// so our Bar pointer is still valid, and we can use it for stuff
some_func_that_takes_bar(specific_data);

Aliasing es para cuando realmente queremos apuntar a Bar, pero tampoco queremos el Foo para ser eliminado de debajo de nosotros.


Como señala Johannes en los comentarios, hay una característica del lenguaje algo equivalente:

const Bar& specific_data = Foo(...).bar;

Estamos tomando una referencia a un miembro de un temporal, pero el temporal Foo todavía se mantiene vivo, siempre y cuando specific_data es. Como con el shared_ptr ejemplo, lo que tenemos es un Bar cuya vida está ligada a un Foo - un Foo que no podemos acceder


37
2017-11-24 16:43