2016-06-28 2 views
9

Это мой кодФункция-член не наследуется?

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

, который не будет компилироваться. Конечно, это будет, если я скажу d.B :: insert (1) в основном, но почему это неверно, как есть? Благодарю.

+0

См. Https://isocpp.org/wiki/faq/strange-inheritance#hiding-rule – Oktalist

ответ

0

Я уверен, что это потому, что вы переопределили функцию «вставить» в D, которая называется вызываемой. Функция «insert» в классе «D» требует двух параметров вместо одного. Выполняя d.B :: insert (1), вы вызываете «вставить» в B.

9

Это связано с тем, что в этом случае функции базового класса не включены в разрешение перегрузки. Аналогичная ситуация связана с функциями, объявленными во внутренней области - они не перегружают функции, объявленные во внешней области (см. Примеры ниже). Вы можете представить, что область производного класса вложена в область базового класса.

После того как компилятор нашел D::insert кандидат, он не будет выглядеть дальше в базовом классе. Если бы не было D::insert, тогда компилятор будет искать базовый класс для метода insert для вызова. Вы можете исправить это, вводя insert имена функций из базового класса с:

using B::insert; 

это будет ввести все B::insert перегруженные функции в производном классе. Или, как вы говорите, вы можете явно вызвать базовый метод класса с:

d.B::insert(1) 

Пример кода на то, как перегрузка работ таким же образом и в других контекстах:

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

или:

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. 
} 
Смежные вопросы