2016-04-14 15 views
0

基本的に私の質問は名前検索とusing宣言(http://en.cppreference.com/w/cpp/language/namespace)に関連しています。
は、我々は、以下の(確かに愚かな)コードがあるとします。2つのまったく同じ名前の名前検索に宣言を使用する効果

class Base { 
public: 
    void fun() 
    {std::cout << "Base fun" << std::endl;} 
}; 

class Derived : public Base { 
public: 
    // Here both names "fun" are visible or not? 
    using Base::fun;//let's call this func_1 

    void fun() //let's call this func_2 
    { 
     std::cout << "Derived fun" << std::endl; 
    } 
}; 

Derived d; 
d.fun(); // This resolves to func_2, why? 

したがって、理解し、私は今、私たちが目に見える両方名前を持つ必要があり、その後、名前の検索のために、いくつかのあいまいさがあるはずです。しかし実際にはそうではありません。理由は何か、言い換えれば、私はいくつかの概念を誤解していますか?

+0

より直接リンクを助けることができる:// ENをあなたはvoid fun()Baseprotectedをしたか、private/protected「LY Base、例から継承されたことをインスタンスになります。 cppreference.com/w/cpp/language/using_declaration – Cubbi

答えて

3

この場合、標準に特別なルールがあります。宣言を使用しては、派生クラスの範囲内に派生クラスのオーバーライドおよび/または非メンバ関数とメンバ関数と テンプレート内のメンバー関数と メンバ関数テンプレートを基本クラスからの名前をもたらし

矛盾ではなく ベースクラスの同じ名前、パラメータタイプリスト(8.3.5)、cv-qualification、ref-qualifier(存在する場合)いつものように、あなたがd.Base::fun()を行うことによって呼び出されるBase::funを強制できること

([namespace.udecl]/15)

注意。

0

あなたが参照しているリンクはnamespace年代のためである、あなたの代わりに、それは述べてclass using-declarationを参照してください:

を派生クラスがすでに同じ名前、パラメータリストを持つメンバーを持っている場合、および派生クラスメンバは、基底クラスから導入されたメンバを隠すか、またはオーバーライドします(矛盾しません)。 Baseであなたの投稿コード、void fun()の場合

Derivedvoid fun()によって隠されているので、あなたがfunを呼び出すときに、明示的でない限り、いや、彼らは、両方の「見え」じゃない、例:

class Base { 
    public: 
     void fun() { std::cout << "base" << std::endl; } 
}; 

class Derived : public Base { 
    public: 
     using Base::fun; 
     void fun() { std::cout << "derived" << std::endl; } 
}; 

Derived d; 
d.fun(); // name lookup calls Derived::fun 
d.Base::fun(); // explicitly call Base::fun 

また、Baseから一般に公開されているため、厳密に言えば、using宣言は必要ありません。

#include <iostream> 

class Base { 
    public: 
     void fun() { std::cout << "base" << std::endl; } 
    protected: 
     void fun2() { std::cout << "base2" << std::endl; } 
}; 

// class default is private 
class Private : Base { 
    public: 
     // fun() won't be accessible since private inheritance and no using 
     // fun2 can now be accessed directly 
     using Base::fun2; 
}; 

class Public : public Base { 
    public: 
     // fun is already public 
     using Base::fun2; // bring into scope 
}; 

class Derived : public Base { 
    public: 
     using Base::fun; 
     using Base::fun2; 

     // overriden method fun, no conflict, choose this method if type is Derived 
     void fun() { std::cout << "derived" << std::endl; } 
}; 

int main(int argc, char* argv[]) 
{ 
    Private p; 
    Public u; 
    Derived d; 

    // generates a compiler error since Base is privately inherited 
    //p.fun(); 
    p.fun2(); // OK, output: base2 

    u.fun(); // OK, output: base 
    u.fun2(); // OK, output: base2 

    // use Derived::fun since override 
    d.fun(); // OK, output: derived 
    d.Base::fun(); // OK, output: base 
    d.fun2(); // OK, output: base2 

    return 0; 
} 

希望のhttpだろう

関連する問題