A me sembra che sia probabilmente trascritto con precisione. Sfortunatamente, il consiglio è per lo più obsoleto (nella misura in cui è stato sempre buono). Il libro in questione è stato scritto nel 1995 e aggiornato nel 1997. Molto è successo negli ultimi 15 anni che rende questo consiglio obsoleto.
Il consiglio si basa sulla nozione di una classe non banale che implementa la "proprietà remota" - cioè, contenente uno o più puntatori ai dati di sua proprietà che saranno allocati nel negozio gratuito. Esempi ovvi sono cose come std::string
e std::vector
, ognuno dei quali normalmente alloca un blocco di memoria per contenere i dati nel contenitore (e l'oggetto string
o vector
stesso contiene solo il puntatore e un piccolo numero di dati contabili , ad esempio la dimensione del blocco assegnato e il numero di elementi nel blocco attualmente in uso).
La ragione per cui dico che è obsoleto è che nella maggior parte dei casi, non dovresti usare i puntatori raw per la proprietà remota. Invece, dovresti in genere utilizzare un puntatore intelligente (ad esempio unique_ptr
o shared_ptr
) per gestire la proprietà remota. Questo puntatore intelligente dovrebbe implementare la "politica" di proprietà remota (copia, assegnazione, distruzione) dei dati che possiede.
Quindi la classe non banale aggregherà semplicemente un'istanza (o più di una, a seconda) per gestire i suoi dati remoti. Nel processo, ottiene la corretta politica di proprietà implementata da quei puntatori intelligenti. Di conseguenza, di solito non avrà bisogno di implementare qualsiasi di quanto sopra.
Questo lascia tipicamente solo la costruzione che deve essere gestita dalla classe non banale. Anche in questo caso si limitano a "distribuire" i dati alla classe base e / o agli oggetti aggregati, quindi il corpo del ctor è spesso vuoto:
class foo {
std::unique_ptr<T> data;
public:
foo(T const &input) : data(make_unique(input)) : {}
};
In conclusione: una classe non banale dovrebbe presentare una visione logica di un'astrazione. Dovrebbe occuparsi quasi esclusivamente della logica dell'astrazione che rappresenta. Dovrebbe raramente (se mai) trattare direttamente direttamente problemi di basso livello, orientati alla lingua come allocazione, cancellazione e copia della memoria necessaria per rappresentare l'astrazione che rappresenta.
Questi problemi dovrebbero essere quasi sempre affrontati da classi di livello inferiore progettate anche per rappresentare un'astrazione - ma in questo caso, un'astrazione abbastanza semplice di "dati di proprietà remota", che sa come gestire cose come copiare, assegnare e distruggendo i dati che possiede, con poco o nessun aiuto dalla classe che lo possiede (ad esempio, la classe proprietaria che passa alcuni argomenti di funzione per dire come distruggere i dati di proprietà). Almeno in molti (la maggior parte?) Casi tipici, una delle classi puntatore nella libreria standard (come il summenzionato unique_ptr
o shared_ptr
) sarà del tutto adeguata a questo compito.
Di conseguenza, raramente è necessario definire il proprio costruttore di copia, l'assegnazione della copia o il distruttore. Questi problemi dovrebbero in genere essere gestiti da classi di livello inferiore dedicate alla fornitura della proprietà remota.
Riferimenti e ulteriori letture:
- link
- link