2016-06-28 18 views
9

Questo è il mio codiceLa funzione membro non è stata ereditata?

class B { 
public: 
    virtual void insert(int t, int p) = 0; 

    void insert(int t) { 
    insert(t, 0); 
    } 
}; 

class D : public B { 
public: 
    void insert(int t, int p) { } 

}; 

int main() { 
    D d; 
    d.insert(1); 
} 

che non verrà compilato. Certo, lo sarà se dico d.B :: insert (1) in main, ma perché è errato così com'è? Grazie.

+0

Vedere https://isocpp.org/wiki/faq/strange-inheritance#hiding-rule – Oktalist

risposta

0

Sono sicuro che è perché hai ridefinito la funzione "inserisci" in D, che è quella che viene chiamata. La funzione "insert" nella classe "D" richiede due parametri invece di uno. Facendo d.B :: insert (1), si sta chiamando "insert" in B.

9

Questo perché in questo caso le funzioni di classe di base non sono incluse nella risoluzione di sovraccarico. Una situazione simile è con le funzioni dichiarate nell'ambito interno - non sovraccaricano le funzioni dichiarate nell'ambito esterno (vedi esempi sotto). È possibile immaginare che l'ambito della classe derivata sia nidificato nell'ambito della classe base.

Una volta che il compilatore ha trovato D::insert candidato non guarderà oltre nella classe base. Se non ci fosse il numero D::insert, il compilatore esaminerà la classe base per il metodo insert da chiamare. È possibile risolvere questo problema introducendo insert nomi delle funzioni da classe di base con:

using B::insert; 

questo introdurrà tutte le B::insert funzioni sovraccaricate in classe derivata. O come dici tu, è possibile chiamare in modo esplicito il metodo della classe base con:

d.B::insert(1) 

codice di esempio per opere come sovraccarico nello stesso modo in altri contesti:

namespace Outer { 
    void foo(double d) { 
    std::cout << "Outer::foo(double d)\n"; 
    } 
    namespace Inner { 
    //using Outer::foo; // uncomment to see "Outer::foo(double d)" in output 
    void foo(int n) { 
     std::cout << "Inner::foo(int n)\n"; 
    } 
    void callMe() { 
     foo(1.1); 
    } 
    } 
} 

int main() { 
    Outer::Inner::callMe(); // Outputes: Inner::foo(int n) 
} 

o:

void foo(std::string s) { 
    std::cout << "foo(std::string s)\n"; 
} 

void foo(double d) { 
    std::cout << "foo(double d)\n"; 
} 

void foo(int n) { 
    std::cout << "foo(int n)\n"; 
} 

int main() { 
    void foo(int d); // comment out to see foo(double d) in output 
    foo(1.1); // outputs: "foo(int n)", foo(double d) is hidden 
    //foo("hello"); // ups, it wont compile - name lookup in c++ happens before type checking 
        // commenting out `void foo(int d);` above will fix this. 
} 
Problemi correlati