Domanda

Qualcuno è a conoscenza di una funzionalità o tecnica del linguaggio in C++ per impedire a una classe figlia di sovrascrivere un particolare metodo nella classe genitore?

class Base {
public:
    bool someGuaranteedResult() { return true; }
};

class Child : public Base {
public:
    bool someGuaranteedResult() { return false; /* Haha I broke things! */ }
};

Anche se non è virtuale, questo è comunque consentito (almeno nel compilatore Metrowerks che sto utilizzando), tutto ciò che ottieni è un avviso in fase di compilazione relativo all'occultamento della funzione X ereditata non virtuale.

È stato utile?

Soluzione

Un paio di idee:

  1. Rendi privata la tua funzione.
  2. Non rendere virtuale la tua funzione.Ciò in realtà non impedisce tuttavia che la funzione venga oscurata da un'altra definizione.

Oltre a ciò, non sono a conoscenza di una funzionalità del linguaggio che bloccherà la tua funzione in modo tale da impedirne il sovraccarico e da poter essere comunque richiamata tramite un puntatore/riferimento alla classe figlia.

Buona fortuna!

Altri suggerimenti

Quando puoi usare il final specificatore per metodi virtuali (introdotti con C++11), puoi farlo.Lasciatemi citare il mio sito di documenti preferito:

Quando utilizzato in una dichiarazione di funzione virtuale, final specifica che la funzione non può essere sovrascritta dalle classi derivate.

Adattato al tuo esempio sarebbe come:

class Base {
public:
    virtual bool someGuaranteedResult() final { return true; }
};

class Child : public Base {
public:
    bool someGuaranteedResult() { return false; /* Haha I broke things! */ }
};

Una volta compilato:

$ g++ test.cc -std=c++11
test.cc:8:10: error: virtual function ‘virtual bool Child::someGuaranteedResult()’
test.cc:3:18: error: overriding final function ‘virtual bool Base::someGuaranteedResult()’

Quando lavori con un compilatore Microsoft, dai un'occhiata anche a sealed parola chiave.

Sembra che quello che stai cercando sia l'equivalente del linguaggio Java finale parola chiave che impedisce che un metodo venga sovrascritto da una sottoclasse.

COME altri ecco suggerito, non puoi davvero impedirlo.Inoltre, sembra che questo sia piuttosto domande frequenti.

(a) Non penso che rendere la funzione privata sia la soluzione perché ciò nasconderà semplicemente la funzione della classe base dalla classe derivata. La classe derivata può sempre definire una nuova funzione con la stessa firma.(b) Anche rendere la funzione non virtuale non è una soluzione completa perché, se la classe derivata ridefinisce la stessa funzione, si può sempre chiamare la funzione della classe derivata tramite associazione in fase di compilazione, ovvero obj.someFunction() dove obj è un'istanza di classe derivata.

Non penso che ci sia un modo per farlo. Inoltre, vorrei sapere il motivo della tua decisione di vietare alle classi derivate di sovrascrivere le funzioni della classe base.

Per chiarimenti, la maggior parte di voi ha frainteso la sua domanda.Non sta chiedendo se "ignorare" un metodo, si sta chiedendo se esiste un modo per impedire di "nascondersi" o meno.E la risposta semplice è che "non ce n'è!".

Ecco ancora una volta il suo esempio

La classe genitore definisce una funzione:

int foo() { return 1; }

Classe figlia, ereditando il genitore definisce ANCORA la stessa funzione (senza sovrascrivere):

int foo() { return 2; }

Puoi farlo su tutti i linguaggi di programmazione.Non c'è nulla che impedisca la compilazione di questo codice (tranne un'impostazione nel compilatore).Il meglio che otterrai è un avvertimento che stai nascondendo il metodo del genitore.Se chiami la classe figlia e invochi il metodo foo, otterrai 2.Hai praticamente decifrato il codice.

Questo è ciò che chiede.

un avviso in fase di compilazione relativo all'occultamento della funzione ereditata non virtuale X.

modificare le impostazioni del compilatore per renderlo un errore anziché un avviso.

Immagino che ciò di cui il compilatore ti avverte si stia nascondendo !!Viene effettivamente sovrascritto?

il compilatore potrebbe fornire un avviso, ma in fase di esecuzione, il metodo della classe genitore verrà chiamato se il puntatore è di tipo classe genitore, indipendentemente dal tipo effettivo dell'oggetto a cui punta.

Questo è interessante.Prova a creare un piccolo programma di test autonomo per il tuo compilatore.

Stavo cercando la stessa cosa e ieri sono arrivato a questa domanda [piuttosto vecchia].

Oggi ho trovato una bella parola chiave c++11: final .Ho pensato che potrebbe essere utile per i prossimi lettori.

http://en.cppreference.com/w/cpp/lingua/final

Se affronti la classe figlia come un tipo del suo genitore, una funzione non virtuale chiamerà la versione della classe genitore.

cioè:

Parent* obj = new Child();

A meno che non rendi virtuale il metodo, la classe figlia non può sovrascriverlo.Se vuoi impedire alle classi figlie di chiamarlo, rendilo privato.

Quindi per impostazione predefinita C++ fa quello che vuoi.

Cercare di impedire a qualcuno di utilizzare lo stesso nome della tua funzione in una sottoclasse non è molto diverso dal provare a impedire a qualcuno di utilizzare lo stesso nome di funzione globale che hai dichiarato in una libreria collegata.

Puoi solo sperare che gli utenti che intendono utilizzare il tuo codice, e non quello di altri, stiano attenti a come fanno riferimento al tuo codice e che utilizzino il tipo di puntatore corretto o utilizzino un ambito completo.

Nel tuo esempio, nessuna funzione viene sovrascritta.Esso è invece nascosto (è una sorta di caso degenerato di sovraccarico).L'errore è nel codice della classe Child.Come suggerito da csmba, tutto ciò che puoi fare è modificare le impostazioni del compilatore (se possibile);dovrebbe andare bene finché non usi una libreria di terze parti che nasconde le proprie funzioni.

Tecnicamente puoi impedire che le funzioni virtuali vengano sovrascritte.Ma non sarai mai in grado di cambiare o aggiungere altro.Questo non è un aiuto completo.È meglio usare il commento davanti alla funzione come suggerisce faq lite.

I metodi C++ sono privati ​​e non sovrascrivibili per impostazione predefinita.

  • Non è possibile sovrascrivere un metodo privato
  • Non è possibile sovrascrivere un non-virtual metodo

Ti riferisci forse al sovraccarico?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top