[問題] R6025 pure virtual function call

看板C_and_CPP作者 (大頭 ..)時間13年前 (2012/03/28 22:45), 編輯推噓4(4017)
留言21則, 5人參與, 最新討論串1/1
註1, 原範例code有更新 http://codepad.org/BdrNfkNv 註2, 找到問題了 平常call的時候沒事 只有在Parent destructor會出事 想請問要怎麼解 .. //-- 原問題 原先的code會造成pure virtual function call 想請問版上各位先進 架構應該怎麼改 或是要怎麼解決這問題 有兩個類別, 以下是程式碼摘要, 僅列出重要部份. class Parent { public: Parent(){}; virtual ~Parent(){ func(); }; int func(){ puts( "in func"); func2(); return 0; } virtual int func2()= 0; }; 以及 class Child : public Parent { public: Child(){}; ~Child(){}; protected: int func2(){ puts( "in func2"); return 0; } }; Child* child= new Child(); child->func();// OK delete child;// Crash 上述程式編譯ok 但是run time會有問題 他call到純虛擬的那個了 程式原本這樣安排是想讓該物件執行func1功能 但是各個繼承Parent的必須實作此func1的部份功能 看來這樣邏輯上有些錯誤 請問各位先進要怎麼改正會比較好 因為小弟OO觀念比較弱 還在學 請多多指教 謝謝 .. -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 123.110.131.43

03/28 23:04, , 1F
你的code我執行起來沒問題喔(除了class{}後面要有分號
03/28 23:04, 1F

03/28 23:04, , 2F
以及child.func1應該是child->func1) 會不會是你沒節錄
03/28 23:04, 2F

03/28 23:04, , 3F
的其他程式碼有問題?
03/28 23:04, 3F
不好意思 倚賴text editer自動校正成習慣了 ..

03/28 23:05, , 4F
Parent* child= new Child(); 改這樣看看
03/28 23:05, 4F

03/28 23:09, , 5F
忽略上面推文,程式是正常的
03/28 23:09, 5F

03/28 23:12, , 6F
語意上不太對,你在 main 裡,擁有 child 物件本體,既然
03/28 23:12, 6F

03/28 23:12, , 7F
你真正想要呼叫的是 Child::fun2() 就直接 child.fun2()
03/28 23:12, 7F
VC++ 2005 今天跑時run time會出現 R6025 pure vurtual function call 在執行func2時就會報錯 如果不是錯在這裡 可能要等明天才能在看一下code 目前手中電腦看不到 或許是我記錯了? 但是我記得弱註解掉func1裡call func2的那行就不會有問題 .. 在func1尾巴執行func2是為了其他繼承Parent的類別 能記得(必須)實作不同的func2 以完成func1 還是我能用其他的方法達到相同的目的嗎?

03/28 23:26, , 8F
要用多型只能用指標吧
03/28 23:26, 8F
不好意思 不大明白您所指的是?

03/28 23:50, , 9F
virtual destructor
03/28 23:50, 9F
應該不是這個問題吧?

03/29 00:09, , 10F
http://codepad.org/7efdDUT5 這樣是你的意思嗎原PO
03/29 00:09, 10F
所以意思是該抽離一個介面 指定說哪些需要客製實做 Parent則實做共同功能 在Child的func1則call這兩個部份 理解這樣沒錯吧? 謝謝 我試試看 ..

03/29 09:23, , 11F
你給的 sample code 不會有問題,關鍵應該是在其他地方
03/29 09:23, 11F

03/29 09:24, , 12F
比方說在 ctor/dtor 內呼叫 func1/func2
03/29 09:24, 12F
目前光用上面的測試碼 一樣無法重現問題 但因原專案為一個頗大的COM DLL 目前繼續釐清方向 等找到問題再來更新 謝謝大家 .. 目前找到問題了 請看上方code 果然如樓上前輩所言 在virtual destructor有call到func 想請問除了抽出額外一個介面外 有解嗎? 謝謝 ..

03/29 12:07, , 13F
你應該把這個 function call 移到子類別的 dtor 中
03/29 12:07, 13F

03/29 12:08, , 14F
既然你會在 dtor 中呼叫 virtual function
03/29 12:08, 14F

03/29 12:09, , 15F
表示你希望做一些「子類別才知道該怎麼做」的處理
03/29 12:09, 15F

03/29 12:09, , 16F
而子類別的 dtor 就是讓你做這些事的地方
03/29 12:09, 16F

03/29 12:10, , 17F
dtor有嚴格的先後順序關係,父類別的dtor在執行時
03/29 12:10, 17F

03/29 12:11, , 18F
子類別的成員都已經被解構了
03/29 12:11, 18F

03/29 12:11, , 19F
所以在dtor中呼叫virtual function是屬於設計上的錯誤
03/29 12:11, 19F
誠如前面所提到的 這個func有共同的地方 所以在Parent實做共同處 在各個繼承者實做func2 所以目前看起來是得要把func給拆開 然後dtor各自call 還是有其他的建議呢 感謝樓上點破錯誤原因 ※ 編輯: pi31415926 來自: 59.124.167.226 (03/29 13:04)

03/29 14:22, , 20F
把「共同處」寫成protected member function
03/29 14:22, 20F

03/29 14:23, , 21F
然後在子類別的dtor中呼叫那個member function
03/29 14:23, 21F
文章代碼(AID): #1FSoFnZW (C_and_CPP)