In quali circostanze è vantaggioso fornire un'implementazione di una funzione virtuale pura?

StackOverflow https://stackoverflow.com/questions/977543

  •  13-09-2019
  •  | 
  •  

Domanda

In C ++, è legale per dare l'implementazione di una funzione virtuale pura:

class C
{
public:
  virtual int f() = 0;
};

int C::f() 
{
  return 0;
}

Perché mai vuole fare questo?

domanda Correlati: La C ++ faq lite contiene un esempio:

class Funct {
public:
  virtual int doit(int x) = 0;
  virtual ~Funct() = 0;
};

inline Funct::~Funct() { }  // defined even though it's pure virtual; it's faster this way; trust me

Non capisco il motivo per cui il distruttore è dichiarato puro virtuale e quindi implementato; e non capisco il commento perché questo dovrebbe essere più veloce.

È stato utile?

Soluzione

distruttori dichiarata deve sempre essere implementati come l'applicazione li chiamerà come parte della distruzione oggetto derivato.

Altre funzioni virtuali puri possono essere implementate se prevedono la funzionalità utile comune, ma devono sempre essere specializzati. Nel caso, le implementazioni di classe tipicamente derivate potranno effettuare una chiamata esplicita a l'implementazione di base:

void Derived::f()
{
    Base::f();

    // Other Derived specific functionality
}

In genere, si fanno un distruttore virtuale se avete bisogno di fare una classe astratta (vale a dire evitare i casi non deriva dal suo essere creato), ma la classe non ha altre funzioni che sono naturalmente pura virtuale. Credo che la 'fiducia in me è più veloce' sta riferendosi al fatto che, a causa distruttori chiamato come parte di oggetto derivato ripulire non è necessario utilizzare un meccanismo di ricerca vtable, l'attuazione inline può essere sfruttato, a differenza di chiamate tipiche funzioni virtuali .

Altri suggerimenti

Se si dispone di funzionalità così comuni che classe derivata può utilizzare. Ma hanno bisogno di fare altri lavori come-bene.

Quindi la classe derivata implementa la funzione virtuale e chiama la versione base sottostante:

class X: public C
{
    public:
        virtual int f()
        {
            return C::f() + 1; // I am +1 over my parent.
        }
};

appena scoperto che Herb Sutter ha risposto la prima parte di questa domanda nel suo Guru della settimana # 31 .

Buongiorno,

Per quanto riguarda fornendo un'implementazione predefinita per una funzione membro dichiarata in una classe base, l'unico motivo che mi viene in mente in questo momento è in cui si desidera fornire un'implementazione predefinita del comportamento come una scelta possibile implementazione per qualcuno che sta specializzandosi la classe di base.

L'autore della classe derivata possono scegliere di utilizzare l'implementazione predefinita fornito dall'autore classe base, invece di aggiungere una propria implementazione specializzati.

Questo è generalmente il caso in cui le persone oggetto ad avere funzioni separate per fornire un'interfaccia e un'implementazione predefinita del comportamento ma vogliono ancora separazione tra implementazione predefinita e l'interfaccia associata.

Ah, appena visto il post di @ Martin York, che fornisce un esempio.

In realtà, Scott Meyers discute questo nel suo libro "Effective C ++". E 'voce 36 della 1 ° edizione.

HTH

applausi,

Perché è considerato come mal formata a scrivere:

class Funct {
public:
  virtual int doit(int x) = 0;
  virtual ~Funct() = 0 {};
};

Il distruttore sarà ancora chiamato se si deriva da questa classe. Dichiara tutti i metodi puro virtuale è solo per chiarezza. Si potrebbe anche scrivere in questo modo:

class Funct {
public:
  virtual int doit(int x) = 0;
  virtual ~Funct() {};
};

La classe sarà ancora astratta in quanto almeno un metodo è puro virtuale. Il distruttore è ancora in linea.

Per quanto riguarda la velocità del distruttore virtuale questo è perché il distruttore è definita nel file cpp e non l'intestazione. Ha più a che fare con la dimensione della velocità. E 'spiegato in dettaglio nel "Large-Scale C ++ Software Design". Purtroppo non riesco a ricordare tutti i dettagli, ma penso che funzioni virtuali in linea vengono definiti più volte nel vtable.

C'è una discussione in questa sede: sono funzioni virtuali in linea in realtà un non-senso?

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