2010-11-12 6 views
1

Doublons possibles:
C++ : implications of making a method virtual
Why is 'virtual' optional for overridden methods in derived classes?C++: les classes dérivées et des méthodes virtuelles

Je me demande, quel est le comportement documenté dans le cas suivant:

Vous avez

class A 
{ 
virtual void A() 
{ 
    cout << "Virtual A"<<endl; 
} 
void test_A() 
{ 
    A(); 
} 
} 

class B: public A 
{ 
    void A() 
    { 
    cout << "Non-virtual A in derived class"<<endl; 
    } 

    void test_B() 
    { 
    A(); 
    } 
} 

A a; B b; 
a.test_A(); 
b.test_A(); 
b.test_B(); 

Qu'est-ce qu'il est censé faire selon la norme C++ et pourquoi? GCC fonctionne comme B :: A est aussi virtuel. Qu'est-ce qui devrait se produire en général lorsque vous remplacez la méthode virtuelle par une méthode non virtuelle dans une classe dérivée?

+6

Votre code [ne devrait pas compiler] (http: //ideone.com/gI9bI). –

+0

Je pense que ceci est également répondu ici: http://stackoverflow.com/questions/2963965/why-is-virtual-optional-for-overridden-methods-in-derived-classes – mkj

Répondre

3

La fonction de membre de sous-classe est implicitement virtuelle si une fonction de membre de classe de base virtuelle avec le même nom et la même signature existe.

+0

@Downvoter: S'il vous plaît expliquer, je veux apprendre. –

+0

Vous devez regarder le code plus attentivement. BTW je n'ai pas baissé. –

+1

Le code ne fonctionne pas, je vois cela, mais j'ai répondu à la question qui a été posée à la dernière ligne. Et à cet égard, ma réponse est correcte. –

0

Selon la norme, il devrait être

 
A a; B b; 
a.test_A(); //"Virtual A" 
b.test_A(); //Non-virtual A in derived class 
b.test_B(); //Non-virtual A in derived class 
0

Ce code est mal formé. Un constructeur ne peut pas avoir un type de retour (comme vous l'avez fait pour le constructeur de 'A'). Un constructeur ne peut pas non plus être virtuel. Après la fixation du constructeur de A, la classe B est mal formée car le constructeur de A est privé. Par conséquent, il existe de nombreux problèmes avec ce code (y compris les points-virgules manquants dans les définitions de classe).

2

Le code ne doit pas être compilé car vous ne pouvez pas nommer une méthode avec le nom de la classe. Mais en ce qui concerne ce que je comprends est votre vraie question:

Est-ce faire une méthode implique virtuelle que la même méthode dans toutes les classes dérivées est virtuel, même si le mot-clé virtual est pas présent?

La réponse est oui. Une fois qu'une méthode est déclarée virtuelle dans une classe, tous les remplacements de cette méthode seront virtuels et le mot-clé virtual est facultatif dans les classes dérivées (même si je recommande de le taper, ne serait-ce qu'à des fins de documentation). Notez que pour une méthode dans une classe dérivée pour être un remplacement il doit avoir le même nom et la signature, avec seule différence de potentiel étant un type de retour covariant:

struct A {}; 
struct B : A {}; 
struct base { 
    virtual A* foo(); 
    virtual A* bar(); 
}; 
struct derived : base { 
    virtual B* foo(); // override, covariant return type 
    virtual int bar(); // not override, return type is not covariant 
    virtual A* bar(int); // not override, different argument list 
}; 
+0

Oui: Je suppose. La dernière partie de la question est exactement celle-là. +1 – Chubsdad

Questions connexes