Re: [閒聊] 今天面試問的問題

看板C_and_CPP (C/C++)作者 (allstars)時間14年前 (2011/12/16 01:49), 編輯推噓5(5020)
留言25則, 4人參與, 最新討論串2/2 (看更多)
我看到這篇舊的文章 但不太清楚pa->f(1.0)的行為 我跑的結果是A::f(double) 前面的 b.f(1.0)會call B::f(complex<double>) 如果是因為A::f(int) A::f(double) 被hide 所以只能B:f(complex<double>) by implict type coversion 那同樣原因的話 pa->f(1.0) 為什麼會call到A::f(double) A::f不是被hide了??? 如果這裡A::f沒有被hide的話 為什麼這情況不會被hide?? 這個case B::f(comple<double>)算有override A::f(double)嗎??? (implict type conversion) 如果不是override的話 那pa裡的vtable A::f(double)還在 所以從vtable 找到A::f(double) 但如果是override的話 他又是如何call到A::f(double)的? 可以說明一下為什麼會call 到A::f(double)呢 謝謝 ※ 引述《cplusplus (沒事多聊天~ 歡迎打屁)》之銘言: : 其中一題,我覺得蠻有趣的 : class A : { : public: : virtual void f(int); : virtual void f(double); : virtual void g(int i=10); : virtual void h(); : }; : class B: public A : { : public: : void f(complex<double>); : void g(int i=20); : void h(int); : }; : int main() : { : A a; : B b; : A *pa=new B(); : B *pb=new B(); : a.f(1.0); : b.f(1.0); : pa->f(1.0); : a.g(); : b.g(); : pa->g(); : pb->g(); : a.h(); : b.h(); : pa->h(); : pb->h(); : delete pa; : delete pb; : return 0; : } : 以上的每個member function call實際上是呼叫到哪個實體? 傳入的參數是? : 有可能出現甚麼問題呢? : 不會很難(因為我都會,顆顆XD), : 但是觀念要有。大家可以無聊看看。 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 220.130.135.229

12/16 02:13, , 1F
pa 是指向 A 物件的指標, compiler 只會知道指到的是個 A
12/16 02:13, 1F

12/16 02:14, , 2F
所以自然只會用 A 所知的下去呼叫
12/16 02:14, 2F

12/16 02:14, , 3F
即使指向的物件其實是 B 也一樣
12/16 02:14, 3F

12/16 02:15, , 4F
要知道雖然是 hide 了但那個還是在 只是 B 那裡看不到而已
12/16 02:15, 4F

12/16 12:47, , 5F
謝謝 那請問樓上的這個說法如何說明pa->g()呢?
12/16 12:47, 5F

12/16 13:07, , 6F
因為 pa 的型別是A*,所以它代入的預設參數是10
12/16 13:07, 6F

12/16 13:08, , 7F
但g()又是virtual function所以呼叫到的是B::g()
12/16 13:08, 7F

12/16 13:10, , 8F
default parameter是compiler在呼叫端幫你填上去的
12/16 13:10, 8F

12/16 13:14, , 9F
繼承的時候應該避免修改參數預設值 否則滿容易搞出bug
12/16 13:14, 9F

12/16 15:08, , 10F
參數預設值是編譯時決定,但是虛擬函數是執行期決定
12/16 15:08, 10F

12/16 15:10, , 11F
推薦Effective C++,裡面有提到這個問題
12/16 15:10, 11F

12/16 15:32, , 12F
那可以麻煩littleshan說明一下pa->f(1.0)嗎
12/16 15:32, 12F

12/16 15:33, , 13F
因為我想知道為什麼pa->f pa->g 兩個behavior不一樣
12/16 15:33, 13F

12/16 15:34, , 14F
另外先不考慮default argument在g的問題喔 謝謝
12/16 15:34, 14F

12/16 16:21, , 15F
f 其實沒有被 override 相同參數的函式
12/16 16:21, 15F

12/16 16:22, , 16F
只有因為同名函式被定義所以父類的同名函式被隱藏了
12/16 16:22, 16F

12/16 16:22, , 17F
也就是說其實 B 裡仍然有"三個"f
12/16 16:22, 17F

12/16 16:23, , 18F
但從 B 那兒叫只能呼叫到 B 裡定義的那一個
12/16 16:23, 18F

12/16 16:23, , 19F
g 的情形則是相同參數的函式 因此它正是被 override
12/16 16:23, 19F

12/16 16:23, , 20F
所以在決定呼叫誰時 virtual 就會起作用
12/16 16:23, 20F

12/16 16:24, , 21F
這才造成了 pa->f 會去找到 A 的 f pa->g 卻去找到 B 的 g
12/16 16:24, 21F

12/16 16:25, , 22F
有一點可以注意的是 pa->f 是靜態決定的 編譯期即可確定
12/16 16:25, 22F

12/16 16:25, , 23F
但 pa->g 是動態的 執行時才知道要呼叫哪個 g
12/16 16:25, 23F

12/16 16:26, , 24F
(下次要改掉這種推文成篇的壞習慣...囧)
12/16 16:26, 24F

12/16 21:13, , 25F
謝謝!
12/16 21:13, 25F
文章代碼(AID): #1EwZCJJr (C_and_CPP)
討論串 (同標題文章)
本文引述了以下文章的的內容:
完整討論串 (本文為第 2 之 2 篇):
文章代碼(AID): #1EwZCJJr (C_and_CPP)