2010-07-19 15 views
1

J'ai une classe comme ceci:C++ question de l'héritage

class A 
{ 
    public: 
     virtual void foo() { bar() } 

    protected: 
     virtual void bar() { /* do stuff */ } 
} 

Maintenant, je veux une classe B dérivée qui remplace foo et bar. J'ai donc écrit ce qui suit:

class B : public A 
{ 
    public: 
     virtual void foo() { A::foo(); /* then other stuff */ } 

    protected: 
     virtual void bar() { /* do different stuff */ } 
} 

Tout compile mais quand j'invoque B :: foo Je me attends au bar de B pour obtenir (éventuellement) appelé. Au lieu de cela, je reçois A :: bar. Qu'est-ce que je fais mal?

+3

Vous avez oublié d'incrémenter tous vos pointeurs de 42. –

+1

Comment avez-vous déclaré votre instance de "B" – reuscam

+1

Pourriez-vous nous montrer comment vous les appelez? – Tom

Répondre

2

avant la mise à jour par l'op.

Cela devrait fonctionner

A* b = new B(); 

b->bar(); //Notice that this is just an example 

Fonctionne également avec des références

void B::foo(){this->bar();} 

    B b; 
    A& ab = b; 
    ab.foo(); //calls B::bar() 
+1

Votre mise à jour n'a aucun sens. S'il * appelait explicitement 'A :: bar', cela serait correct (bien que le' this-> 'soit encore superflu), mais jetez un oeil à son code: il appelle explicitement' A :: foo', à son tour, appelle 'bar()' normalement. Comme 'bar' est virtuel, ceci devrait se résoudre en' B :: bar' comme il s'y attend. –

+0

ok alors je l'enlève – Tom

+1

b-> bar() ne fonctionnera pas car le membre est protégé. Votre redéfinition de B :: foo() n'est pas ce que veut l'OP. Il veut qu'il appelle d'abord l'implémentation de base de A :: foo(). –

9

Tout compile mais quand j'invoque B :: foo-je attendre au bar de B pour obtenir (éventuellement) appelé. Au lieu de cela, je reçois A :: bar. Qu'est-ce que je fais mal?

On dirait que vous ne comprenez pas vraiment ce qui se passait mal dans votre code original, a décidé que le mécanisme de remplacement virtuel doit être le coupable et vous a affiché un exemple de non-travail qui décrit ce que vous êtes enclin à croire, mais que vous n'a pas dérangé pour vérifier, car si vous aviez alors vous avez vu que n'expose pas le comportement décrit. Voici une version compilable de votre exemple.

#include <stdio.h> 
class A 
{ 
    public: 
     virtual void foo() { puts("A:foo()"); bar(); } 

    protected: 
     virtual void bar() { puts("A:bar()"); } 
}; 

class B : public A 
{ 
    public: 
     virtual void foo() { puts("B:foo()"); A::foo(); } 

    protected: 
     virtual void bar() { puts("B:bar()"); } 
}; 


int main() 
{ 
    B b; 
    b.foo(); 
} 

Quand je lance ce je reçois:

$ g++ g++ h.cc 
$ ./a.out 
B:foo() 
A:foo() 
B:bar() 

Donc tout va bien avec B :: bar().

+1

En effet. Le problème est soit avec le code qui crée l'objet et appelle la fonction (ce qui n'a pas été montré), soit avec l'interprétation des résultats. –

0

Outre les points-virgules manquants à la fin des définitions de classe, le code OP actuel fonctionne comme prévu.