日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

虚拟函数的静态决议 和 RTTI 小例子

發布時間:2025/3/20 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 虚拟函数的静态决议 和 RTTI 小例子 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一:先說虛擬函數的靜態決議(Static Resolution)

  在兩種情況下,虛擬函數機制不會出現預期行為:1、在基類的constructor和destructor內;2、當我們使用的是基類的對象,而非基類對象的pointer 或 reference時

  上述第二種情況很好理解,第二種情況是C++多態機制的重要概念。第一種情況其實也很簡單,但我才剛開始學習C++,怕以后自己會不小心把一些虛函數寫在constructor 或 destructor里,固寫此文章記錄一下,下面給出第一種情況的解釋:

  -----------------摘抄Essential C++解釋開始-----------------

  當我們構造派生類對象時,基類的constructor會先被調用。如果在基類的constructor中調用某個虛擬函數,會發生什么事?調用的應該是派生類所定義的那一份嗎?

  問題出在此刻派生類中的data member尚未初始化。如果此時調用派生類的那一份虛擬函數,它便有可能取用未經初始化的data members,這可不是一件好事。

  基于這個理由,在基類的constructor中,派生類的虛擬函數絕對不會被調用。同理,如果在基類的destructor中調用虛擬函數,此規則同樣成立。

  -----------------摘抄Essential C++解釋結束-----------------

舉例:

  基類代碼

  

1 #pragma once
2 #include <typeinfo>
3 #include <iostream>
4 class num_sequence
5 {
6 public:
7 num_sequence(void);
8 virtual const char* what_am_i() const;
9 virtual void display() const { std::cout << "Based decontroctor" << std::endl; }
10 virtual ~num_sequence(void) { display(); }
11 };

  派生類代碼

  

1 #pragma once
2 #include "num_sequence.h"
3
4 class Fibonacci :
5 public num_sequence
6 {
7 public:
8 Fibonacci(void);
9 virtual void display() const { std::cout << "Drived destructor" << std::endl; }
10 ~Fibonacci(void) { display(); };
11 void testTypeId() { std::cout << "testTypeIdFunction" << std::endl; }
12 };

然后在main里測試:

  Fibonacci fib;
  num_sequence *ps = &fib;

輸出的結果是:

  Derived destructor
  Based destructor
  請按任意鍵繼續. . .

即:分別調用子類和基類的析構函數(調用基類的析構函數時,基類析構函數里的display()函數沒有動態執行子類的display())

?

二:RTTI

  基類num_sequence.cpp中加入

inline const char* num_sequence::what_am_i() const
{
return typeid( *this ).name();
}

主main程序里面:

  

1 Fibonacci fib;
2 num_sequence *ps = &fib;
3
4 if ( typeid(*ps) == typeid(Fibonacci) )
5 {
6 ps->Fibonacci::testTypeId(); // 錯誤
7 ps->testTypeId();// 錯誤
8 if ( Fibonacci *pf = dynamic_cast<Fibonacci*> (ps) )
9 {
10 pf->testTypeId();
11 }
12 }

  Line6、Line7錯誤,這里ps并不"知道"它所尋址的對象實際上是什么型別--縱使我們知道,typeid及虛擬函數機制也知道。。

  為了調用Fibonacci所定義的testTypeId(),我們必須指示編譯器,將ps的型別轉換為Fibonacci指針。

  1、static_cast可以轉換:Fibonacci *pf = static_cast<Fibonacci*>( ps );

  但存在危險,因為編譯器無法確認我們所進行的轉換操作是否完全正確。

  2、dynamic_cast:這是一個RTTI運算法,會進行執行期檢驗操作,檢驗ps所指對象是否屬于Fibonacci類。如果是,轉換操作便會發生,于是pf便指向該Fibonacci對象。如果不是,dynamic_cast運算符返回0。

轉載于:https://www.cnblogs.com/ziyoudefeng/archive/2012/03/20/2407907.html

總結

以上是生活随笔為你收集整理的虚拟函数的静态决议 和 RTTI 小例子的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。