Diciamo che abbiamo seguente gerarchia:Come prevenire chiamata alla implementazione base di un metodo
class Abstract
{
public:
virtual void foo() = 0;
};
class Base : public Abstract
{
public:
virtual void foo() override; //provides base implementation
};
class Derived : public Base
{
public:
virtual void foo() override; //provides derived implementation
};
Se Base::foo()
viene mai chiamato sull'oggetto Derived
che oggetto si desincronizzazione ed i suoi dati saranno danneggiati. Assorbe la struttura dei dati di Base
e la sua manipolazione, ma deve eseguire operazioni aggiuntive, quindi chiamare solo il ometterà queste operazioni extra e, di conseguenza, lo stato di Derived
sarà danneggiato.
Perciò vorrei evitare che la chiamata diretta di Base
realizzazione di foo
quindi questo:
Derived d;
d.Base::foo();
idealmente, dovrebbe darmi un errore di tempo di compilazione di alcune specie. O non fare nulla o altrimenti essere prevenuto.
Tuttavia potrebbe essere che sto violando le regole polimorfismo e dovrei usare la composizione, invece, ma che richiederebbe un sacco di battitura a macchina in più ...
Qualcosa non va con 'protected:' piuttosto che 'public:' per quel metodo in 'Base'?Inoltre, questo sembra anche un candidato decente per ridichiarare come puro-virtuale in 'Base' * e * fornendo un'implementazione' Base', che non è comune, ma che accade. Se 'Derived' dovrebbe * sempre * essere implementato, sembrerebbe una scelta accettabile. – WhozCraig
@WhozCraig Non sapevo di poter fornire l'implementazione per il metodo virtuale puro. Questo impedisce che quell'implementazione venga mai chiamata se è stata reimplementata da coloro che la ereditano? – Resurrection
@Resurrection no, è per questo che 'protected' su' Base :: foo' arriverà. Ma ciò che * fa * fa è forzare le classi derivate a fornire ancora override, fornendo anche un'implementazione base comune che possono invocare senza sballottare una funzione membro aggiuntiva nel malessere. – WhozCraig