2016-04-14 51 views
0

基本上,我的問題是有關名稱查找和using聲明(http://en.cppreference.com/w/cpp/language/namespace)。
假設我們有以下的(絕對愚蠢的)代碼:使用聲明名稱查找兩個完全相同的名稱的效果

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

一個更直接的聯繫將是http:// EN。 cppreference.com/w/cpp/language/using_declaration – Cubbi

回答

3

該標準對這種情況有特殊的規定。

using聲明帶來在派生類超控和/或隱藏成員函數和成員函數從基類名轉換成一個派生類範圍,成員函數和 成員函數模板 模板與相同名稱,參數類型列表(8.3.5),cv資格和ref-qualifier(如果有)在 基類(而不是衝突)。

([namespace.udecl]/15)

注意,像往常一樣,你可以強制Base::fun邊做d.Base::fun()調用。

0

你引用的鏈接是namespace的,則應該是指它規定了class using-declaration

如果派生類已經有相同的名稱,參數列表的成員,資格,派生類成員隱藏或覆蓋(不衝突)從基類引入的成員。

在您發佈的代碼的情況下,在void fun()Base通過void fun()Derived當你調用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;您的實例將是void fun()Baseprotected或者你private/protected「從Base,例如LY繼承:

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

希望可以幫助

相關問題