2010-11-03 6 views

risposta

0

In generale questa è una cattiva idea. Molto spesso non sai come è stato creato l'oggetto di ClassB. Potrebbe essere un puntatore a elemento di un array creato con l'operatore new [], o potrebbe essere consegnato a voi dal dll separato che utilizza la memoria personalizzato allocatore. In quei casi l'uso dell'operatore delete per cancellare questo puntatore sarebbe un grave errore.

+0

E di solito, gli utenti di questa API usano solo un ClassB * parametro, può essere creato da nuovo, o solo l'indirizzo di un elemento ClassB. Nel caso successivo, porterà a doppio free. – qiuxiafei

9

La risposta è dipende da. Devi chiarire chi è responsabile della durata dell'oggetto.

Anche ClassA manca un operatore di copia e di costruzione definito dall'utente e questo può portare a un comportamento non definito. Ad esempio:

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 

quindi il tuo esempio probabilmente non è molto buono.

0

Di solito, questo è un disegno confuso/incoerente (normalmente si desidera che lo new e lo corrispondano allo stesso livello). Tuttavia, ci sono alcune eccezioni; ad esempio, i puntatori intelligenti vengono forniti con un puntatore raw e quindi assumono la proprietà dell'oggetto, quindi sono responsabili di invocare delete quando non è più necessario.

1

Solitamente l'utilizzo di puntatori in questo tipo di situazione è di progettazione errata. In questo tipo di situazione i puntatori intelligenti sono i tuoi migliori amici. Tuttavia, se devi usare i puntatori, scegli semplicemente in entrambi i modi e documentalo attentamente

1

Non c'è niente di sbagliato in questo in particolare - tecnicamente hai passato la proprietà a ClassB invece all'istanza ClassA quando è stata creata (cioè un ClassB l'istanza esiste prima della necessità di ClassA, ma una volta creato ClassA diventa il proprietario di una ClasseB).

Se un buon design dipende dal contesto in cui viene applicato. Ad esempio, ha senso che ClassA diventi proprietario di un ClassB? Dovresti usare un puntatore intelligente invece di un puntatore "semplice vecchio"?

2

vuoi dire:

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

Questo non è un buon design. Colui che crea dovrebbe essere colui che cancella.

+0

Anche questa è la mia regola –

1

Come altri hanno già detto, è preferibile evitare questa situazione utilizzando puntatori intelligenti o eliminando un oggetto allo stesso livello in cui è stato creato ... o non utilizzando affatto i puntatori.

Allo stesso tempo, non mi dire che è necessariamente un male di progettazione per trasferire la proprietà dell'oggetto, fino a quando si rendono evidente per gli utenti ClassA nella documentazione. Ho riscontrato una situazione simile durante la scrittura di funzioni che prendono un puntatore a un oggetto e lo copia-lo costruiscono per il proprio uso. Dove necessario, tendo a annotare queste funzioni con "semantica copia parametri" o qualcosa che dice al chiamante "Si può fare quello che si vuole con questo oggetto dopo aver tornare ... Ho la mia copia".

Se si utilizzano puntatori grezzi, considererei importante stabilire questo tipo di contratti di chiamata.

Problemi correlati