2016-06-28 44 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

我敢肯定,这是因为你重新定义了函数“insert”在D中,这是被调用的函数。类“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. 
}