找回密碼 或 安全提問
 註冊
|註冊|登錄

伊莉討論區

搜索
感激所有對伊莉作出奉獻的人發表文章前請先閱讀相關版規搞笑、娛樂、精彩的影片讓你看
海賊王人妻航海王出包王女高中流出
354kamef狩魔領主秘湯ガーrbd 955復讐のオ位於戀愛スラム街

休閒聊天興趣交流學術文化旅遊交流飲食交流家庭事務PC GAMETV GAME
熱門線上其他線上感情感性寵物交流家族門派動漫交流貼圖分享BL/GL
音樂世界影視娛樂女性頻道潮流資訊BT下載區GB下載區下載分享短片
電腦資訊數碼產品手機交流交易廣場網站事務長篇小說體育運動時事經濟
上班一族博彩娛樂

✡ 斗破蒼穹 年番/鬥

[簡]Unnamed Memory

桃園觀音文林路 女子

[繁]迷宮飯16-

[繁]轉生貴族憑鑑定技

[繁]關於我轉生變成史
C & C++ 語言C# 語言Visual Basic 語言PHP 語言JAVA 語言
查看: 1732|回復: 4
打印上一主題下一主題

[問題][已解決]有關虛擬函數的疑問 關閉[複製鏈接]

Rank: 6Rank: 6Rank: 6Rank: 6Rank: 6Rank: 6

帖子
89
積分
174 點
潛水值
51520 米
跳轉到指定樓層
樓主
發表於 2013-9-2 10:13 AM|只看該作者|倒序瀏覽
若對尊貴或贊助會員有任何疑問,歡迎向我們查詢。我們的即時通或MSN: admin@eyny.com
本帖最後由 c780702 於 2013-9-3 10:28 AM 編輯
  1. #include <iostream>
  2. #include <cstdlib>
  3. using namespace std;
  4. class CShape                           // 定義抽象類別CShape
  5. {
  6.    public:
  7.       virtual int area()=0;            // 定義area()為泛虛擬函數
  8.       void show_area()
  9.       {
  10.          cout << "area = " << area() << endl;
  11.       }  
  12.       ~CShape()                              // ~CShape() 解構元
  13.       {
  14.          cout << "~CShape()解構元被呼叫了..." << endl;
  15.          system("pause");
  16.       }         
  17. };

  18. class CWin : public CShape             // 定義由CShape所衍生出的子類別CWin
  19. {
  20.    protected:
  21.      int width, height;
  22.      
  23.    public:
  24.      CWin(int w=10, int h=10):width(w),height(h){} // CWin()建構元
  25.      
  26.      virtual int area() {return width*height; }
  27.      
  28.      void show_area() {
  29.         cout << "CWin物件的面積 = " << area() << endl;
  30.      }
  31.      ~CWin()                                                 // ~CWin() 解構元
  32.      {
  33.         cout << "~CWin()解構元被呼叫了..." << endl;
  34.         system("pause");
  35.      }   
  36. };

  37. class CMiniWin : public CWin           // 定義由CWin所衍生出的子類別CMiniWin
  38. {
  39.    public:     
  40.      CMiniWin(int w,int h):CWin(w,h){} // CMiniWin()建構元
  41.      
  42.      virtual int area() {
  43.         return (int) (0.5*width*height);
  44.      }
  45.      void show_area(){
  46.         cout << "CMiniWin物件的面積 = " << area() << endl;
  47.              }      
  48.      ~CMiniWin()                              // ~CMiniWin() 解構元
  49.      {
  50.         cout << "~CMiniWin()解構元被呼叫了..." << endl;
  51.         system("pause");
  52.      }   
  53. };

  54. int main(void)
  55. {
  56.    CShape *ptr=new CWin(50,60);     
  57.    ptr->show_area();
  58.    cout << "銷毀CWin物件..." << endl;
  59.    delete ptr;
  60.    cout << endl;     
  61.    
  62.    ptr=new CMiniWin(50,50);
  63.    ptr->show_area();
  64.    cout << "銷毀CMiniWin物件..." << endl;
  65.    delete ptr;   
  66.    cout << endl;
  67.    
  68.    CMiniWin m_win(100,100);
  69.    m_win.show_area();
  70.    

  71.    system("pause");
  72.    return 0;
  73. }
複製代碼
這個程式碼是錯誤範例
因為61行與67行並不會呼叫正確的show_area()函數
而63行與69行也只會呼叫~CShap()解構元
修正的方法我已經知道了
但我對書本裡對這個程式碼的講解有疑問

書本裡說:
因為執行delete指令時,編譯器所知到的訊息只是ptr的型態為基底類別CShape,而ptr真正指向之物件型態會無法得知,因此編譯器就假設ptr是指向由基底類別所建立之物件。

我的疑問:
然而61行的show_area()函數呼叫是在delete指令之前,60行的CShape *ptr=new CWin(50,60),不是代表ptr指向CWin(50,60)嗎(動態記憶體配置)?這樣ptr怎麼會不知道指向之物件的型態呢?
66.67行的地方也是,ptr也不知道指向之物件的型態,於是便呼叫錯誤的show_area()函數。
...
瀏覽完整內容,請先 註冊登入會員

點評

c780702 已改  發表於 2013-9-2 04:54 PM
c780702 光碟裡的,想說貼在文中排版似乎會變醜,也沒有顏色區分,所以就用圖片空間了@@  發表於 2013-9-2 04:49 PM
snowflying 這程式碼是書上的? 如果是自己寫的,請避免使用 "圖片" 的方式  發表於 2013-9-2 04:18 PM
分享分享0收藏收藏0支持支持0
分享使你變得更實在,可以使其他人感到快樂,分享是我們的動力。今天就來分享你的資訊、圖片或檔案吧。

使用道具檢舉

Rank: 1

帖子
126
積分
87 點
潛水值
4060 米
頭香
發表於 2013-9-2 10:52 AM|只看該作者
如果你忘記伊莉的密碼,請在登入時按右邊出現的 '找回密碼'。輸入相關資料後送出,系統就會把密碼寄到你的E-Mail。
你先拋開上下文,ptr是CSharp類型,destructor和show_area都是普通的成員函數。
當你寫
ptr->show_area()
的時候,編譯器肯定是去CSharp這個類里找函數執行啊。

如果show_area是一個virtual function。
那麼在*ptr的最前面几個字節,會存放一個指針,指向vtable
然后然后show_area這個函數會固定的在vtable中對應一項,比如第二項,或者第四項。

不同的class,他們的instance的vtable不一樣。
...
瀏覽完整內容,請先 註冊登入會員
如果發覺自己無法使用一些功能或出現問題,請按重新整理一次,並待所有網頁內容完全載入後5秒才進行操作。

使用道具檢舉

Rank: 6Rank: 6Rank: 6Rank: 6Rank: 6Rank: 6

帖子
89
積分
174 點
潛水值
51520 米
3
發表於 2013-9-2 05:00 PM|只看該作者
如果你忘記伊莉的密碼,請在登入時按右邊出現的 '找回密碼'。輸入相關資料後送出,系統就會把密碼寄到你的E-Mail。
本帖最後由 c780702 於 2013-9-2 05:01 PM 編輯

vtable書本裡並沒有提到
但在我自己上網搜尋時也有找到一些文章
不過......理解得有些模糊阿

大部分的文章結論是
如果程式碼裡有使用抽象類別,且用指標指向它的話,建議把基底類別裡要留給子類別改寫的函數與解構元均設為virtual
...
瀏覽完整內容,請先 註冊登入會員
如果你忘記伊莉的密碼,請在登入時按右邊出現的 '找回密碼'。輸入相關資料後送出,系統就會把密碼寄到你的E-Mail。

使用道具檢舉

  尊貴會員

Melty Snow  雪靈

Rank: 6Rank: 6Rank: 6Rank: 6Rank: 6Rank: 6

帖子
3222
積分
24364 點
潛水值
77140 米
4
發表於 2013-9-2 06:05 PM|只看該作者
若對尊貴或贊助會員有任何疑問,歡迎向我們查詢。我們的即時通或MSN: admin@eyny.com
本帖最後由 snowflying 於 2013-9-2 08:19 PM 編輯
c780702 發表於 2013-9-2 05:00 PM
下載: 訪客無法瀏覽下載點,請先 註冊登入會員

vtable書本裡並沒有提到
但在我自己上網搜尋時也有找到一些文章
不過......理解得有些模糊阿
...
瀏覽完整內容,請先 註冊登入會員

點評

c780702 我知道,所以我也很頭痛...ORZ  發表於 2013-9-2 08:16 PM
snowflying 很多文件都是原文的  發表於 2013-9-2 08:11 PM
c780702 唔...還是有點難,我研究研究~"~ 大大提供的連結我先放一旁,因為看不懂英文(汗...)  發表於 2013-9-2 08:10 PM
Melty Snow [雪靈]

使用道具檢舉

Rank: 1

帖子
126
積分
87 點
潛水值
4060 米
5
發表於 2013-9-2 09:17 PM|只看該作者
本帖最後由 kym3 於 2013-9-2 09:20 PM 編輯

C++中的類型可以分為POD類型和非POD類型。POD是plain old type。


通俗來說,POD類型就是C語言里面的struct和union。凡是有虛函數的,都不是POD類型。...
瀏覽完整內容,請先 註冊登入會員





點評

c780702 非常的詳細,謝謝大大費心替我講解,我大概明白了:)  發表於 2013-9-2 10:05 PM
如果瀏覽伊莉時速度太慢或無法連接,可以使用其他分流瀏覽伊莉,www01.eyny.com(02,03)。

使用道具檢舉

您需要登錄後才可以回帖 登錄 | 註冊

Powered by Discuz!

© Comsenz Inc.

重要聲明:本討論區是以即時上載留言的方式運作,對所有留言的真實性、完整性及立場等,不負任何法律責任。而一切留言之言論只代表留言者個人意見,並非本網站之立場,用戶不應信賴內容,並應自行判斷內容之真實性。於有關情形下,用戶應尋求專業意見(如涉及醫療、法律或投資等問題)。 由於本討論區受到「即時上載留言」運作方式所規限,故不能完全監察所有留言,若讀者發現有留言出現問題,請聯絡我們。有權刪除任何留言及拒絕任何人士上載留言,同時亦有不刪除留言的權利。切勿上傳和撰寫 侵犯版權(未經授權)、粗言穢語、誹謗、渲染色情暴力或人身攻擊的言論,敬請自律。本網站保留一切法律權利。
回頂部