2012-03-08 15 views
7
class Parent { 
public: 
    void func1(); // Complete meaningful definition in parent given. 

    virtual HRESULT func2()=0; // Bcoz of this function Parent class is abstract. 
}; 


class Child: public Parent { 
public: 
    void func1(); // Different definition in child. 
}; 

E 'possibile in C++? Sto sovrascrivendo func1() che NON è virtuale e ha già una definizione nella classe astratta genitore.È possibile sovrascrivere una funzione in classe figlio C++ senza utilizzare la parola chiave virtuale per la funzione nella classe genitore che è astratta?

+0

È possibile eseguire l'override, ma l'uso di puntatori/riferimenti di classe di base per il proprio figlio non darebbe un comportamento polimorfico. – birryree

+0

Risposta semplice: No! Altrimenti la parola chiave virtual è senza senso. – knivil

+0

@knivil: È possibile, e la parola chiave 'virtuale' ha un significato - sta solo facendo qualcos'altro [il comportamento cambierà completamente!], È * nascondendo *' func1() 'nella superclasse, e non attivando la dinamica spedizione. – amit

risposta

19

[assumendo qui Child estende Parent, a differenza di quanto scattare il codice spettacoli]

Sì, è possibile [si chiama nascondiglio] - ma non sarà possibile ottenere un comportamento dynamic dispatch.

Il tipo statico definirà quale metodo verrà richiamato e non il tipo dinamico.

Ad esempio:

Parent* p = new Child; 
p->func1(); 

invocherà Parent::func1()
mentre:

Child* c = new Child; 
c->func1(); 

invocherà Child::func1()

+0

Grazie mille per questo !! :) Ho visto 2 risposte contraddittorie che dicevano 1) E 'possibile e 2) Non è possibile. Vedendo 7 persone (maggioranza ppl) considerando l'opzione (1) corretta, sto considerando che questa è la risposta giusta. :) – codeLover

+0

Non lo è. La risposta dice "sì è possibile", ammette quindi che non lo è, che in realtà si nasconde. Tuttavia, la descrizione di ciò che accadrà è accurata. E accettare una risposta solo perché ha il punteggio più alto è un po 'sciocco. –

+0

Ancora più importante, se alcuni altri metodi dall'implementazione di Parent chiamano func1, chiameranno sempre la versione di Parent. E nessuna schifezza di tipo "statico" ti aiuterà ad aggirare il problema. – user2451227

2

Puoi sovraccarico che, se hanno tipi di argomenti distinti.

È possibile nasconderlo esso, nel senso qui illustrato, in modo che Child::func1 si chiamerà invece di Parent::func1 nel codice che sa che sta guardando un'istanza bambino. Tuttavia, come indicato da amit, non si ottiene la spedizione dinamica.


struct StaticParent { 
    void foo(); 
}; 
struct StaticChild : public StaticParent { 
    void foo(); 
} 

StaticChild sc; 
sc.foo(); // calls StaticChild::foo 

StaticParent &sp = sc; 
sp.foo(); // calls StaticParent::foo 

struct VirtualParent { 
    virtual void foo(); 
}; 
struct VirtualChild : public VirtualParent { 
    virtual void foo(); 
} 

VirtualChild vc; 
vc.foo(); // calls VirtualChild::foo 

VirtualParent &vp = vc; 
vp.foo(); // calls VirtualChild::foo 
0

Sì, questo è valido sintassi C++ e definirà un bambino :: func1 che nasconde parent :: func1 in bambino.

Tuttavia, questo non significa che sostituisce completamente Child :: Parent :: func1. Questa funzione può ancora essere chiamata esplicitamente su un elemento di child.

Child c; 
c.Parent::func1(); 

Inoltre, questa funzione non essere virtuale. Quindi, il seguente ..

Child c; 
Parent& p = c; 
p.func1(); 

chiamerà Parent :: func1 e non Child :: func1.

3

No, non è possibile in realtà ignorare la definizione nel genitore (almeno quando si parla di C++, "override" è normalmente riservato in modo specifico al riferimento alle funzioni virtuali). Invece, definendo una funzione con lo stesso nome nella classe figlio, semplicemente nasconde la funzione nella madre che ha lo stesso nome (cioè, nel contesto di un oggetto figlio, la ricerca di quel nome troverà la funzione solo nel bambino , non quello nel genitore).

Se si vuole (e le funzioni hanno diverse firme) è anche possibile ottenere le funzioni, sia il genitore e il bambino trattato come sovraccarico, quindi una chiamata cercherà di chiamare a seconda di quale corrisponde meglio:

struct parent { 
    void func1(char) {} 
}; 

struct child : public parent { 
    void func1(long) { } 

    using parent::func1; 
}; 

Ora, si ottiene:

child c; 
c.func1('a'); // calls parent::func1 
c.func1(123L); // calls child::func1 

Questo è ancora un terzo tipo di comportamento, però, diverso dall'avere una funzione virtuale o avere una funzione nel bambino che nasconde quello nel genitore.

Con una funzione virtuale, la selezione di quale funzione viene chiamata si basa sul tipo dinamico, quindi se si ha un puntatore/riferimento alla classe base, la funzione chiamata dipende dal fatto che si riferisca ad un oggetto della base o classe derivata.

Quando si nasconde la funzione, la funzione chiamata è basata sul tipo statico, quindi se la si chiama tramite un puntatore/riferimento alla base, chiama la funzione di base, anche se in realtà si riferisce a un oggetto di la classe derivata. Se, tuttavia, si utilizza un puntatore o un riferimento a (o direttamente un'istanza di) la classe derivata, verrà richiamata la funzione nella classe derivata.

Con l'istruzione using, si ottiene un sovraccarico della funzione, quindi quando si chiama la funzione (nel contesto della classe derivata) la funzione chiamata si basa sulla firma della funzione che è la migliore corrispondenza per il/i parametro/i passaggio.

0

La maggior parte è stata detta.

Le tue aspettative sarebbero giuste se parli di java. In java qualsiasi metodo non privato, non finale potrebbe essere sovrascritto. Forse siete più familiarità con un altro linguaggio di programmazione di C++

A proposito, due cose sono sbagliate nel codice

  • minuscolo "classe" deve essere scritto accesso
  • il default di i membri della classe sono "private". NON è consentito né utile ignorare i membri privati ​​che non sono puri
+1

* NON è consentito né utile sostituire i membri privati ​​* non è vero? C'è un intero idioma (* Non Virtual Interface *) costruito sul fatto che tu puoi ** e tu ** dovresti **. –

+0

Hmm, ho sentito questo termine la prima volta. Googling per esso aumenta la mia confusione. –

Problemi correlati