2015-02-12 41 views
0
class Base { 
    public: 
    virtual int f() const { 
     cout << "Base::f()\n"; 
     return 1; 
} 
virtual void f(string) const {} 
virtual void g() const {} 
}; 

class Derived4 : public Base { 
    public: 
     int f(int) const { 
     cout << "Derived4::f()\n"; 
     return 4; 
    } 
}; 

int main() 
{ 
    string s("hello"); 

    Derived4 d4; 
    Base& br = d4; // Upcast 
    // br.f(1); // Derived version unavailable 
    br.f(); // why does it compile and run? 
    br.f(s);// why does it compile and run? 
} 

在派生:超載f()的基地..所以所有基地f()版本應該隱藏。現在
,爲br.f()br.f(S):因爲運行時綁定,f()和衍生f(s)的應該叫,但他們應該被隱藏,還是代碼編譯和執行INT基地:: f()和void Base :: f(string)。運行時綁定和虛擬繼承

Q1:我在想什麼?
Q2:br.f(1)不編譯,因爲在編譯期間執行類型檢查,並且int f(int)不在基址中。我對麼?

+1

你不會在派生類中重載任何東西!函數f的原型與基類中函數f的任何原型都不相同。另外,還不清楚「隱藏」是什麼意思。函數'f()'和'f(string)'在基類中是'public',因此調用基類對象時不應該有任何問題。 – 2015-02-12 07:52:51

+0

Base ::'int f()',Derived ::'int f(int)',你的意思是這不是重載? – 2015-02-12 08:01:30

+0

它們是隱藏的,所以如果你嘗試'd4.f()'和'd4.f(s)',它將不會被編譯。但'br'的類型是'Base',編譯器不知道它的真實類型('Derived4'),所以'br.f()'和'br.f(s)'都可以。 – songyuanyao 2015-02-12 08:14:37

回答

1

基類從來不知道派生類中新增加的成員,它只有關於聲明自己的成員的信息。
因此,當派生類實例d4被分配給基類參考br時,新添加的方法int f(int) const被隱藏到br。這就是爲什麼下面的代碼

// br.f(1); // Derived version unavailable 

在編譯如下錯誤雙線成功編譯

br.f(); 
br.f(s); 

更多的瞭解:

class Base { 
    public: 
    virtual int f() const { 
     cout << "Base::f()\n"; 
     return 1; 
} 
virtual void f(string) const {} 
virtual void g() const {} 
}; 

class Derived4 : public Base { 
    public: 
     int f(int) const { 
     cout << "Derived4::f()\n"; 
     return 4; 
    } 
    void g() const { 
     cout<< "Derived4::g()" << endl; 
    } 
}; 

int main() 
{ 
    string s("hello"); 

    Derived4 d4; 
    Base& br = d4; // Upcast 
    // br.f(1); // Derived version unavailable 
    br.f(); // No Compilation error 
    br.f(s);// No Compilation error 

    d4.f(); // Compilation error 
    d4.f(s); // Compilation error 
    d4.f(1); // No Compilation error 
    d4.g(); // No Compilation error 
    br.g(); // Will print - "Derived4::g()" 
} 

希望它能幫助!

0

功能int Derived4::f(int)隱藏從基類功能,但不倍率它們。要做到這一點,它應該有完全相同的簽名。

如果功能覆蓋,則可以調用基類引用上的函數並查看被調用的派生類函數。