2012-06-18 3 views
5

Supongamos que tengo la necesidad de hacer lo siguiente (Este es solo un código imaginativo para la discusión del estándar C++, por lo tanto no discutiré por qué lo diseño de esta manera, así que no me moleste con algo como: su diseño es un error.)La misma dirección, varios contadores shared_ptr, ¿está prohibida por el estándar C++?

T* ptr = new T; 
shared_ptr<T> p(ptr); 
shared_ptr<T> q(ptr, SomeDeleterThatDoesnotDeleteButDoSomeOtherStuff()); 

Supongamos que la lógica garantiza que p o algunos de sus copias vive más tiempo que todas las copias de q, por lo que prácticamente no habrá ningún problema. Mi pregunta es, ¿está prohibido por el estándar de C++, p. explícitamente establecido como UB por C++ estándar, para diferentes contadores shared_ptr para compartir la misma dirección?

Gracias.

+1

¿Qué pasa si 'devuelve q;'? –

+0

@Peter Creo que esa es la idea: invocar a los no delegados y hacer algo útil con el conocimiento de que algún subconjunto de referencias está ahora vacío. – Potatoswatter

+0

El diseño no es * que * terrible para su propósito. Puede garantizar la destrucción adecuada al reemplazar el eliminador personalizado por uno que * lo hace * eliminar, y también posee su propio 'shared_ptr' 1. con un objeto ficticio que realiza la acción en su destructor o 2. tiene otro eliminador personalizado que realiza la acción . Pero esos métodos podrían ser menos eficientes si los conjuntos de objetos 'q' cambian rápidamente en relación con el conjunto de propietarios adecuados' p'. – Potatoswatter

Respuesta

2

No encuentro nada en el estándar (bueno, el borrador final) que específicamente lo excluye. El más cercano que puedo encontrar es una nota en 20.9.11.2.10 shared_ptr casts

5 [Nota: La expresión equivalente al parecer shared_ptr (static_cast (r.get())) con el tiempo como resultado un comportamiento indefinido , intentar eliminar un mismo objeto dos veces. -finalizar nota]

que en realidad parece olvidarse de su caso con un eliminador personalizado.

5

Si se destruye el primer objeto shared_ptr, obtiene UB porque los objetos que usan el segundo pueden acceder al objeto liberado.

Como se aseguró de que su primer objeto shared_ptr viva más tiempo que el segundo, no obtiene UB.

Cuestiones relacionadas