Consideriamo la seguente classe da estendere:
struct A {
int x, y;
A(int x, int y) : x(x), y(y) {}
};
È possibile ereditare da questa classe o scrivere una classe wrapper che contiene un'istanza di questa classe. Nella maggior parte dei casi, l'ereditarietà è la strada da percorrere, come una classe wrapper non è una A, ma avvolge (contiene) una A.
Con C++ 11 semantica muoversi, promuovere un'istanza A
a una sottoclasse B
(ereditando A
) sarà efficace e non richiede di copiare l'istanza A
:
class B : public A {
public:
B (A &&a) : A(a), someOtherMember(a.x + a.y) {}
// added public stuff:
int someOtherFunction() const { return someOtherMember; }
private:
// added private stuff:
int someOtherMember;
};
codice completo con l'esempio: http://ideone.com/mZLLEu
Naturalmente la funzione aggiungo ed è un po 'sciocco (e il membro ancora di più, dal momento che non rispetta ulteriori cambiamenti dei membri originali x
e), ma dovresti avere un'idea di ciò che voglio dimostrare.
Nota il costruttore B (A &&a)
che è qualcosa che chiamo "promuovi costruttore" (questo non è un termine standard). Normalmente, move constructor, che sposta il contenuto dell'istanza B
fornita in un nuovo B
in procinto di essere costruito. Io uso la semantica di spostamento su sposta un'istanza di A
(che è stata restituita da un'altra funzione) in la super-classe A
di B
.
In modo efficace, è possibile promuovere A
a B
rendendo possibile l'utilizzo di B
come A
.
In contrasto con la risposta di Soonts, la mia soluzione funziona anche con tabelle virtuali aggiunte, poiché non si basa sul casting puntatore non sicuro.
Sì, Se si ha accesso alla definizione di classe. No altrimenti. –
In fase di esecuzione non si ottiene alcun supporto linguistico per questo. Tuttavia, puoi farlo utilizzando per es. una mappa contenente puntatori di funzione. Ma questo è piuttosto ingombrante e soggetto a errori. –
@AlokSave Intendi modificare direttamente il codice sorgente? Potrebbe essere un'opzione. – Eonil