2016-06-28 6 views
9

To jest mój kodFunkcja członkowska nie jest dziedziczona?

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); 
} 

który nie będzie skompilować. Oczywiście, jeśli powiemy d.B :: insert (1) w main, ale dlaczego jest to niepoprawne, tak jak jest? Dzięki.

+0

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

Odpowiedz

0

Jestem prawie pewien, że to dlatego, że przedefiniowałeś funkcję "wstaw" w D, która jest tą, która zostaje wywołana. Funkcja "wstaw" w klasie "D" wymaga dwóch parametrów zamiast jednego. Robiąc d.B :: insert (1), wywołujesz "insert" w B.

9

Dzieje się tak, ponieważ w tym przypadku funkcje klasy podstawowej nie są uwzględnione w rozdzielczości przeciążania. Podobnie jest z funkcjami zadeklarowanymi w wewnętrznym zasięgu - nie przeciążają one funkcji zadeklarowanych w zewnętrznym zakresie (zobacz przykłady poniżej). Można sobie wyobrazić, że pochodny zakres klasy jest zagnieżdżony w zasięgu klasy podstawowej.

Po znalezieniu kompilatora D::insert nie będzie wyglądać dalej w klasie bazowej. Gdyby nie było D::insert, kompilator przyjrzy się klasie bazowej dla metody wywołania insert. Można rozwiązać ten problem poprzez wprowadzenie insert nazwy funkcji z klasy bazowej z:

using B::insert; 

ten wprowadzi wszystkie B::insert przeciążone funkcje te w klasie pochodnej. Albo jak mówisz, można jawnie wywołać Base Class metodę z:

d.B::insert(1) 

kodu próbki do prac jak przeciążenia w taki sam sposób w innych kontekstach:

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) 
} 

czyli

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. 
} 
Powiązane problemy