2016-06-28 3 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); 
} 

です。確かに、mainでd.B :: insert(1)と言ってもそれは間違っているのでしょうか?ありがとう。

+0

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

答えて

0

私は、あなたが呼び出されるものであるDに関数 "insert"を定義し直したことは確信しています。クラス "D"の関数 "insert"には、1つではなく2つのパラメータが必要です。 d.B :: insert(1)を実行すると、Bに "insert"が呼び出されます。

9

これは、オーバーロード解決に基本クラス関数が含まれていないためです。同様の状況は、内部スコープで宣言された関数であり、外部スコープで宣言された関数をオーバーロードしません(下記の例を参照)。派生クラススコープが基本クラススコープ内にネストされていると想像できます。

コンパイラがD::insert候補を見つけたら、それは基本クラスではそれ以上見えません。 D::insertがない場合、コンパイラはinsertメソッドを呼び出すための基本クラスを探します。これは、派生クラス内のすべてのB::insertオーバーロード関数を紹介します

using B::insert; 

:あなたが基本クラスから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. 
} 
関連する問題