Vuoi un "mixin". In C ++ vengono solitamente implementati con modelli e in particolare utilizzando CRTP, il "modello di modello curiosamente ricorrente" . Potrebbe essere eccessivo se si tratta solo di un codice comune, che la risposta di Pierre sembra più appropriata. Ma man mano che cresce la quantità di codice comune per le classi di simulazione, anche il valore del modello.
CRTP di base sarebbe come questo:
template <typename ConcreteT> class Mock {
initMock() {
static_cast<ConcreteT *>(this)->x = 1;
static_cast<ConcreteT *>(this)->y = "abc";
static_cast<ConcreteT *>(this)->z = 0.5;
}
};
class MockA : A, Mock<MockA> { ... };
// ^^^^^ specialized on the type that inherits it, that's the point
Qui renderebbe semplice ereditare A attraverso la classe Mock, quindi
template <typename BaseT> class Mock : public BaseT {
initMock() {
x = 1;
y = "abc";
z = 0.5;
}
};
class MockA : Mock<A> { ... };
// ^ just the base class
Questo elimina i brutti static_casts, ma non ti consente di fornire metodi in MockA
che verranno chiamati da Mock
. Ma puoi avere entrambi ...
template<typename ConcreteT, typename BaseT>
class Mock : public BaseT { ... };
class MockA : Mock<MockA, A> { ... };
Ora Mock
può chiamare i metodi di MockA
su se stesso tramite il cast statico e i metodi call di A
(o meglio la base finale) direttamente.
Nota: i template di mixin sono fondamentalmente la stessa cosa di mixin in Ruby o interfacce con implementazioni di metodi introdotte in Java 8. Questi linguaggi sono un costrutto speciale, perché non hanno nulla della potenza dei template C ++, ma l'implementazione è simile: una classe intermedia è costruita dal compilatore e inserita nella gerarchia.