#include<iostream.h>
class A{ public:
virtual void show(int a=145){cout<<"A: a="<<a<<endl; }
};
class B:public A
{ public:
void show(int b){ cout<<"B: b="<<b<<endl; }
};
class C:public B
{ public:
void show(int c=999){ cout<<"C: c="<<c<<endl; }
};
class D:public C
{ public:
void show(){ cout<<"D:\n"; }
};
void main()
{ A a,*pa=&a;
B b; C c; D d;
pa=&b; pa->show(77);
pa=&c; pa->show();
pa=&d; pa->show();
}
/*執行結果:B: b=77
C: c=145
C: c=145 */
12 个解决方案
pa=&b; pa->show(77);
這一句你指定了參數77,所以輸出77
pa=&c; pa->show();
這一句采用了默認參數.但是你的a,c都給了一個默認參數,
由於是虛函數,c里面的默認參數無效,輸出145
pa=&d; pa->show();
這里其實你是重新定義了一個函數show,它的參數是void,
已經不是虛函數了.也就是說.d里面有兩個show
總之1.盡量避免重復指定默認參數
2.不是繼承的函數不要用一個名字
這里是錯的.
********************
也就是說.d里面有兩個show
**********************
只有一個,非虛的.
至於為什么可以用指針&d調用到c的那一層的虛函數,
可能是虛機制的結果吧.
>這里是錯的.
>********************
>也就是說.d里面有兩個show
>**********************
D里面有兩個show,但只有一個是對A::show(int)的override,也就是C::show(int);另一個(D::show())只是函數名相同,但注意參數不同,所以函數簽名是不同的,它與A::show(int)是無關的。因此你對一個A*調用->show()操作時,編譯器自然會使用缺省參數145對A*調用show(int)成員,而這個成員是多態成員,它會到VTBL中去查找,最終找到了C::show(int)。因此這個結果是正確的。
為什么?
pa=&d; pa->show();
/*執行結果: C: c=145 */ 非D:
to plainsong(短歌) :
thank you.
我開始確實對這個地方有點誤解,
差點誤導別人.多謝
to 樓主:
pa=&d; pa->show();
這就是虛函數調用,由於d沒有改寫這個virtual show(int),
所以調用了c的.
你自己定義的void show(){ cout<<"D:\n"; }(它是個普通成員函數)
隱藏了它繼承而來的虛函數