C++ 編譯報錯 undefined reference to “vtable for child”

先說結果: 父類定義的虛函數,子類如果重載了 ,那就必須定義具體實現,不能弄個沒有函數體的函數名放那裏碰瓷。 

  1. #include<iostream>
  2. using namespace std;
  3. class parent
  4. {
  5. public:
  6. parent(){
  7. std::cout<<"parent constructor no param"<<std::endl;
  8. };
  9. private:
  10. parent(int a){
  11. std::cout<<"parent constructor: "<<a<<std::endl;
  12. };
  13. public:
  14. virtual ~parent(){
  15. std::cout<<"parent disconstructor~"<<std::endl;
  16. };
  17. virtual void opt(){
  18. std::cout<<"parent opt"<<std::endl;
  19. };
  20. };
  21. class child:public parent
  22. {
  23. public:
  24. child(int a){
  25. cout<<"child constructor: "<<a<<endl;
  26. };
  27. ~child();
  28. void opt(){
  29. std::cout<<"child opt"<<std::endl;
  30. };
  31. void child_do(){
  32. std::cout<<"child do"<<std::endl;
  33. };
  34. };
  35. int main()
  36. {
  37. int b = 10;
  38. parent* test = new child(b);
  39. test->opt();
  40. reinterpret_cast<child*>(test)->child_do();
  41. delete parent;
  42. return 0;
  43. }
  1. /tmp/cc3sxtLw.o: In function `child::child(int)':
  2. test.cpp:(.text._ZN5childC2Ei[_ZN5childC5Ei]+0x1d): undefined reference to `vtable for child'

找了好一會,發現是子類的析構函數只是聲明瞭,沒有定義,

改成 ~child(){}; 定義上就好了。

但是我記得之前也有過忘記定義析構函數具體內容的情況,編譯並沒有報錯,

於是回過頭注意到 這句報錯的含義好像並不是說子類的析構函數沒有定義,

undefined reference to `vtable for child' -> 對child的虛表未定義的引用,

這裏 vtable 應該就是指的虛函數表,

嘗試着換一種方式修改 ~child(); 這個不變, 把 virtual ~parent 改爲 ~parent,

果然 也不報錯了,但是我們都知道這樣改的後果是啥,就是父類指針指向的子類對象析構不會調用子類的析構函數了。

  1. [root@iZuf6iemoke3l0asocwqo5Z 繼承]# ./a.out
  2. parent constructor no param
  3. child constructor: 10
  4. child opt
  5. child do
  6. parent disconstructor~
  7. [root@iZuf6iemoke3l0asocwqo5Z 繼承]#

所以,老老實實給父類的析構函數加上 virtual, 然後完善對子類析構函數的定義.

  1. virtual ~parent(){
  2. std::cout<<"parent disconstructor~"<<std::endl;
  3. };
  4. ~child(){
  5. cout<<"child disconstructor"<<endl;
  6. };

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章