2010-11-03 14 views

Respuesta

0

En general, esta es una mala idea. A menudo, simplemente no sabes cómo se creó el objeto de ClassB. Podría ser un puntero al elemento de una matriz creada con el nuevo operador [], o podría transferirse a usted desde una DLL independiente que utiliza un asignador de memoria personalizado. En esos casos, usar el operador delete para eliminar este puntero sería un error grave.

+0

Y generalmente, los usuarios de esta API solo usan una ClassB * parámetro, puede ser creado por nuevo, o simplemente la dirección de un elemento ClassB. En el caso posterior, dará lugar a doble gratis. – qiuxiafei

9

La respuesta es depende. Debe dejar en claro quién es responsable de la duración del objeto.

También ClassA carece de un constructor de copias y un operador de asignación definidos por el usuario y esto puede conducir a un comportamiento indefinido. Por ejemplo:

ClassA object1(new ClassB()); //object1 takes ownership of the object 
ClassA object2(object1); //object2 takes ownership of the same object 
// now first object2 is destroyed and deletes the object 
// then object1 is destroyed and double-delete happens 

por lo que es probable que su ejemplo no sea muy bueno.

0

Normalmente, no, este es un diseño confuso/inconsistente (normalmente desea que new y delete correspondan en el mismo nivel). Sin embargo hay algunas excepciones; por ejemplo, los punteros inteligentes se proporcionan con un puntero sin formato y luego toman posesión del objeto, por lo que son responsables de invocar delete cuando ya no es necesario.

1

Normalmente el uso de punteros en este tipo de situación es un mal diseño. En este tipo de situación, los indicadores inteligentes son tus mejores amigos. Sin embargo, si tiene que usar punteros, simplemente elija cualquiera de los dos y documente cuidadosamente

1

No hay nada de malo en esto específicamente: técnicamente ha pasado la propiedad de ClassB en lugar de la instancia de ClassA cuando se creó (es decir, un ClassB la instancia existe antes de que se necesitara ClassA, pero una vez que se crea ClassA, se convierte en el propietario de una clase B).

Si el diseño es bueno o no depende del contexto en el que se aplica. Por ejemplo, ¿tiene sentido que ClassA tome posesión de un ClassB? ¿Debería utilizar un puntero inteligente en lugar de un puntero "antiguo"?

2

Qué quiere decir:

class ClassA { 
    ClassB *b; 
public: 
    ClassA(ClassB * p) {b = p;} 
    ~ClassA() {delete b;} 
}; 

Esto no es un buen diseño. El que crea debe ser el que borre.

+0

Esa es mi regla también –

1

Como han dicho otros, es preferible evitar esta situación mediante el uso de punteros inteligentes o eliminando un objeto al mismo nivel que se creó ... o al no usar punteros en absoluto.

Al mismo tiempo, no diría que es necesariamente un mal diseño para transferir la propiedad del objeto, siempre y cuando lo haga obvio para los usuarios de ClassA en la documentación. He encontrado una situación similar al escribir funciones que toman un puntero a un objeto y lo compilan para su propio uso. Donde sea necesario, tiendo a anotar estas funciones con "semántica de copia de parámetros" o algo que le dice a la persona que llama "Puedes hacer lo que quieras con este objeto después de que regrese ... Tengo mi propia copia".

Si está utilizando punteros sin procesar, consideraría importante establecer este tipo de contratos de llamadas.

Cuestiones relacionadas