2009-09-27 4 views
7

Sto affrontando un problema in C++:C++ problema di override/sovraccarico

#include <iostream> 

class A 
{ 
protected: 
    void some_func(const unsigned int& param1) 
    { 
    std::cout << "A::some_func(" << param1 << ")" << std::endl; 
    } 
public: 
    virtual ~A() {} 
    virtual void some_func(const unsigned int& param1, const char*) 
    { 
    some_func(param1); 
    } 
}; 

class B : public A 
{ 
public: 
    virtual ~B() {} 
    virtual void some_func(const unsigned int& param1, const char*) 
    { 
    some_func(param1); 
    } 
}; 

int main(int, char**) 
{ 
    A* t = new B(); 
    t->some_func(21, "some char*"); 
    return 0; 
} 

sto usando g ++ 4.0.1 e l'errore di compilazione:

$ g++ -W -Wall -Werror test.cc 
test.cc: In member function ‘virtual void B::some_func(const unsigned int&, const char*)’: 
test.cc:24: error: no matching function for call to ‘B::some_func(const unsigned int&)’ 
test.cc:22: note: candidates are: virtual void B::some_func(const unsigned int&, const char*) 

Perché devo specificare che la chiamata di some_func (param1) nella classe B è A :: some_func (param1)? È un bug g ++ o un messaggio casuale da g ++ per prevenire casi particolari che non vedo?

+0

Questo è strano. Una funzione di classe base protetta dovrebbe essere visibile a una sottoclasse, virtuale, sovraccaricata o meno. –

risposta

11

Il problema è che nella classe derivata si nasconde il metodo protetto nella classe base. Puoi fare un paio di cose, o qualificare completamente il metodo protetto nell'oggetto derivato oppure portare questo metodo in scope con una direttiva using:

+0

Perché lo nascondo? Sto semplicemente ignorando il secondo. Normalmente, g ++ deve mantenere la firma dell'iniz in overload nella vtable di B, ma non è questo il caso. Perché non mantiene le firme di ogni metodo? Perché perde il sovraccarico (sto solo ridefinendone uno)? – fedj

+1

Quando si definisce un metodo con un nome in una classe derivata, verranno nascosti tutti gli altri metodi con lo stesso nome sopra nella gerarchia. Quando il compilatore scopre che stai chiamando 'some_func' attraverso un riferimento di tipo statico B cercherà di farlo corrispondere a tutte le occorrenze di' some_func' all'interno di B stesso e non tenterà di scalare la gerarchia per trovare possibili corrispondenze nelle classi base. –

+0

È un comportamento predefinito di g ++ per evitare grandi dimensioni vtable o è la definizione C++ e ogni compilatore produrrà lo stesso errore? Perché normalmente, se non fosse un sovraccarico in classe A (diciamo un altro nome di metodo), la firma sarebbe stata copiata nella classe B vtable. – fedj