子類中using引入基類函數(shù)時需要注意的情況 收藏
子類中using引入基類函數(shù)時需要注意的情況
class base{
public:
void test(){
cout << "base::test()" << endl;
}
void test(int){
cout << "base::test(int)" << endl;
}
};
class derived : public base{
public:
void test(){
cout << "derived::test()" << endl;
}
};
此時derived::test()會隱藏(hide)父類中的兩個test重載函數(shù)(base::test()和base::test(int)),因此我們?yōu)樽宇愔屑由弦粋€using聲明:
class derived : public base{
public:
void test(){
cout << "derived::test()" << endl;
}
using base::test;//此聲明放在test前面和后面效果都一樣
};
現(xiàn)在會不會出現(xiàn)下面所述的情況呢?
---------------------------------------------------------------------------------------------------------------
既然using base::test將父類中的兩個test函數(shù)都引入子類,則子類中就相當(dāng)于有了一個void test()函數(shù),所以我們在子類中重新定義的void test()函數(shù)將會和從父類中引入的void test()函數(shù)發(fā)生沖突,進(jìn)而出現(xiàn)“重定義”錯誤。
---------------------------------------------------------------------------------------------------------------
答案是:不會!
此時,子類中重新定義的void test()函數(shù)將“頂替”從父類中引入的void test()函數(shù)。
(PS:從父類中引入的另外一個void test(int)函數(shù)則沒有發(fā)生變化(仍然是父類中的函數(shù)實現(xiàn))。)
類似的另外一種情況如下,此時加入了virtual:
class base{
public:
virtual void test(){
cout << "base::test()" << endl;
}
virtual void test(double){
cout << "base::test(double)" << endl;
}
void test(int){
cout << "base::test(int)" << endl;
}
};
class derived : public base{
public:
void test(){
cout << "derived::test()" << endl;
}
};
此時derived::test()雖然重寫(override)了base::test(),但是同時也隱藏(hide)父類中的兩個test重載函數(shù)(一個virtual函數(shù)base::test(double)和一個nonvirtual函數(shù)base::test(int))?,F(xiàn)在,我們?yōu)樽宇愔屑由弦粋€using聲明:
class derived : public base{
public:
void test(){
cout << "derived::test()" << endl;
}
using base::test;//此聲明放在test前面和后面效果都一樣
};
與上面的類似,此時derived::test()“仍然重寫”了父類的base::test(),并且與父類中的base::test(double)和base::test(int)[在子類的域]中形成重載集合。
最后,留一個思考題目,如下:
class base{
public:
virtual void test(){
cout << "base::test()" << endl;
}
virtual void test(double){
cout << "base::test(double)" << endl;
}
void test(int){
cout << "base::test(int)" << endl;
}
};
class derived : public base{
public:
void test(){
cout << "derived::test()" << endl;
}
//using base::test;
};
class A : public derived{
public:
void test(double){
cout << "A::test(double)" << endl;
}
};
int main(int argc, char **argv){
base *pb = new A;
pb->test(2.4);
return 0;
}
問題:derived中的using base::test加上與否,對程序的結(jié)果有什么影響?
答:沒有影響。(關(guān)鍵點:名字解析是編譯時期的事情,而virtual函數(shù)動態(tài)綁定是運行時期的事情。)
(PS:但是將main函數(shù)改成“derived *pd = new A; pd->test(2.4);”,則有區(qū)別了:如果將using base::test去掉,則編譯失敗。)
本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請
點擊舉報。