Il problema che affronto è come combinare incapsulamento e utilizzo ottimale della memoria.
Non posso mostrarti il mio codice e quindi spiegarlo in un ampio esempio (spero).
Diciamo che abbiamo bisogno di avere un database di mans. Vogliamo sapere solo 2 cose su quelle persone:
- Età dell'uomo (in ore dalla nascita).
- Nome della città in cui vive.
Il modo comodo e naturale per gestire questi dati è creare un oggetto, che corrisponde a un uomo e memorizzarlo in un array:
class OMan1 {
public:
OMan( const int &age, const astring &t ): fAge(age), fTown(t) {}
const int& age() const: { return fAge; }
const astring& Town() const: { return fTown; }
astring FullId() const: { return fTown+fAge; }
private:
int fAge;
astring fTown;
}
OMan mans[N];
Qui i nostri OM sono oggetti che contengono autonomamente e tutto si riempie bene.
Tranne il fatto che cloniamo i nomi delle città migliaia di volte, e spreciamo memoria e tempo di esecuzione in questo modo.
Un miglioramento che possiamo fare è creare un array indipendente per i nomi di città e per ogni OMan, memorizzare solo l'età, un identificativo della città e un puntatore alla serie di città:
class OMan2 {
// same functionality as for OMan1
int fAge;
int fTownId;
astring* fTowns;
}
l'oggetto è ancora autonomo, sizeof(int) + sizeof(void*)
è molto meno di sizeof(astring)
, vinciamo molto. Tuttavia, è ancora 2-3 volte più del sizeof(fAge)
e ripetiamo fTowns
miliardi di volte.
L'ottimizzazione della memoria è fondamentale per me, quindi quello che faccio è mantenere solo fAge
e fTownId
e spostare tale funzionalità come Town()
e FullId()
fuori dalla classe OMan
in una classe come OManDataBase
:
class OMan3 {
public:
OMan( const int &age, const int &tid ): fAge(age), fTownId(tid) {}
const int& age() const: { return fAge; }
const int& TownId() const: { return fId; }
// const astring& Town() const: { return fTown; }
// astring FullId() const: { return fTown+fAge; }
private:
int fAge;
int fTownId;
}
class OManDataBase {
// constructor, destructor
const int& age( const int& i) const: { return fMans[i].TownId()]; }
const astring& Town( const int& i) const: { return fTown[fMans[i].TownId()]; }
const astring& FullId( const int& i) const: { return Town(i)+age(i); }
private:
vector<OMan3> fMans;
vector<astring> fTowns;
}
E OMan3
ora non è un oggetto autonomo. Ad esempio, non riconosce il suo nome completo. Ciò significa che se ho bisogno di fare un po 'di elaborazione dei dati con un uomo devo usare l'intera% istanza diOManDataBase
:
OBillType47 NewBillType47( const OManDataBase &db, int i ) { ... }
invece di
OBillType47 NewBillType47( const OMan &m ) { ... }
l'incapsulamento è stato interrotto qui e la leggibilità del codice è stata chiaramente ridotta. (Ho messo Type47
per sottolineare che posso avere un sacco di funzioni, che funziona con Oman-S
e non posso includerle tutte in OManDataBase
class).
Mi chiedo c'è un altro modo (-s) per risolvere il problema della duplicazione dei dati, mantenendo gli oggetti il più possibile autosufficienti ?