【C/C++】C++之private虛擬函式
一般我們說虛擬函式,它的訪問級別都是public的,用類物件可以直接呼叫,這樣就可以實現執行時的型別繫結,那如果我們將虛擬函式私有化會出現什麼情況呢?
我們先來看一個非虛擬函式私有化的例子
class Base { private: void PrintClassName () { cout<<"Base"<<endl; } public: void print() { PrintClassName(); } }; class Derived : public Base { private: void PrintClassName() { cout<<"Derived"<<endl; } };
在main函式裡產生一個Derived的物件d,然後呼叫print()函式,即d.print(),結果輸出的卻是Base,print()函式沒有呼叫子類的PrintClassName函式,而是呼叫父類的PrintClassName函式,原來是由於PrintClassName函式不是虛擬函式之故,所以Base的print()函式呼叫PrintClassName()函式是在編譯時就已經綁定了,而不是執行期繫結。
下面我們讓PrintClassName()函式變成虛擬函式再執行,就可以看到輸出的類名為子類的名稱,即Derived。
那麼我們有沒有辦法呼叫私有的虛擬函式呢?當然是有的,不管公有還是私有,只要是虛擬函式,它的函式地址都會放在虛擬函式表vftable中,只要我們找到虛擬函式表中存放的PrintClassName()函式的地址,我們就可以直接呼叫,前提是你必須對C++類物件的記憶體佈局要熟悉,程式碼如下,這樣也輸出Derived,與前面效果相同
int _tmain(int argc, _TCHAR* argv[]) { Derived d; //d.print(); typedef void (*Fun)(); Fun pFun = NULL; pFun = (Fun)*((int*)(*(int *)&d + 0) + 0); pFun(); getchar(); return 0; }
相關推薦
【C/C++】C++之private虛擬函式
一般我們說虛擬函式,它的訪問級別都是public的,用類物件可以直接呼叫,這樣就可以實現執行時的型別繫結,那如果我們將虛擬函式私有化會出現什麼情況呢? 我們先來看一個非虛擬函式私有化的例子 class Base { private: void Prin
【C/C++開發】C++之enum列舉量宣告、定義、使用與列舉類詳解與列舉類前置型別宣告
前面講到可以通過強制轉換將其他型別值賦給列舉變數:Weekday = enumType(2);這是合法的;但是Weekday = enumType(20);是非法的。這裡涉及列舉取值範圍的概念:列舉的上限是 大於最大列舉量的 最小的2的冪,減去1; 列舉的下限有兩種情況:一、列舉量的最小值不小於0,則列
【C++札記】C++物件模型之記憶體佈局
對於C++的學習,我看了C++ Primer之後,進階的書為深入理解C++物件模型,這本書講解了C++類在記憶體中是如何佈局以及成員函式是怎麼呼叫,有助於理解C++多型是如何實現的.總之,受益匪淺. 無多型的物件佈局 單個類: 假設有以下一個類的定義:
【wif 系列】C#之單例模式(Singleton)最佳實踐(一)
com value 快捷 lock 詳細介紹 筆記本 改進 奇怪 我不知道 目錄 介紹 第一個版本 ——不是線程安全的 第二個版本 —— 簡單的線程安全 第三個版本 - 使用雙重檢查鎖定嘗試線程安全 第四個版本 - 不太懶,不使用鎖且線程安全 第五版 - 完全懶惰的實例化
【設計模式】C#版三大工廠之簡單工廠、工廠方法與抽象工廠
引言 簡單工廠、工廠方法、抽象工廠都屬於設計模式中的建立型模式。其主要功能都是幫助我們把物件的例項化部分抽象取了出來,優化了系統的架構,並且增強了系統的擴充套件性。此篇部落格是筆者對學完這三種模式之後一個小小的總結 簡單工廠 簡單工廠模式的工
【C++】在繼承中虛擬函式、純虛擬函式、普通函式,三者的區別
1.虛擬函式(impure virtual) C++的虛擬函式主要作用是“執行時多型”,父類中提供虛擬函式的實現,為子類提供預設的函式實現。 子類可以重寫父類的虛擬函式實現子類的特殊化。 如下就是一個父類中的虛擬函式: class A { public: virt
【學習筆記】C# 構造和析構
成員 int 學習 pri [] func 釋放內存 ring 銷毀 構造方法 構造方法是一個特殊的方法,負責初始化對象 構造方法名必須和類名一致 構造方法沒有返回值,但可以有參數,能夠重載 構造方法可以不寫,系統會自動為類添加一個無參的默認構造 如果將構造方法設置為P
【學習筆記】C# 靜態類
實例化 namespace [] line str 過程 ole test 數據 靜態修飾符 用static修飾的成員是靜態成員 靜態成員只能由類來調用 用static修飾的類是靜態類 靜態類不能實例化,只能包含靜態成員和const常量 在內存中一共有五個區域 1
【學習筆記】C# 接口
apple [] oat 訪問 names 使用 foo pub 修飾 使用interface關鍵字定義接口 接口定義一組成員但不直接實現它們 實現接口 實現接口的任何類都必須實現其所有的成員方法 接口不能直接實例化 接口可以包含方法和屬性聲明,不能包含字段 接口中所有
【學習筆記】C# ArrayList
tde 獲取 style demo key ren mov cnblogs content 集合 集合是種容器,在程序中,使用集體管理相關對象組 集合分為非泛型集合和泛型集合 非泛型集合 使用非泛型集合需要引入命名空間System.Collections Arra
【學習筆記】C# 字典
鍵值對 保存 包含 ear 是否 nod 對象 命名空間 不包含 字典 Dictionary是存儲鍵和值的集合 Dictionary是無序的,鍵Key是唯一的 使用時,首先要引入泛型集合命名空間 using System.Collections.Generic;
【tmp post】c++模板
spa fun public blog temp nbsp class col tmp 2017-12-29 1 // see file functional: class function<_Res(_ArgTypes...)> 2 template&l
【問題記錄】C#調用WebApi的PUT&DELETE方法報405錯誤
head 2008r2 功能 工作 http 錯誤 控制面板 面板 int 問題環境:Windows Server 2008R2 IIS7.5 問題描述:網站調用後臺數據接口,GET和POST方法正常,PUT和DELETE方法報 405 Method
【TOJ 5247】C++實驗:時間和日期類
OS 日期類 一行 ID 表示 pac 日期 style pub 描述 用C++實現日期類CDate和時間類CTime,並在次基礎上利用多繼承實現日期時間類CDateTime,使其能輸出樣例信息。 主函數裏的代碼已經給出,請補充完整,提交時請勿包含已經給出的代碼。 int
【TOJ 5254】C++實驗:繼承中的構造函數和析構函數
des 能夠 con OS esp space AC tom cto 描述 實現C++類Base和Derived,並編寫相關構造函數和析構函數,使其能夠輸出樣例信息。 主函數裏的代碼已經給出,請補充完整,提交時請勿包含已經給出的代碼。 int main() { Base
【TOJ 5255】C++實驗:三角形面積(海倫公式)
esc man opera time public 三角形面積 AC pac 公式 描述 實現C++三角形類,其中包含3個點(CPoint類型),並完成求面積。主函數裏的代碼已經給出,請補充完整,提交時請勿包含已經給出的代碼。 int main() { CPoint p
【TOJ 5240】C++實驗:虛函數
spa turn medium virtual AI CI edi time ont 描述 用C++實現一個形狀類和矩形類,並完成求面積函數。 主函數裏的代碼已經給出,請補充完整,提交時請勿包含已經給出的代碼。 int main() { int w, h; while
【編譯原理】c++實現自下而上語法分析器
不可 acm times style size PC -i 表達式 鏈接 寫在前面:本博客為本人原創,嚴禁任何形式的轉載!本博客只允許放在博客園(.cnblogs.com),如果您在其他網站看到這篇博文,請通過下面這個唯一的合法鏈接轉到原文! 本博客全網唯一合法URL:ht
【讀書筆記】C#本質論第一章
environ 系列 駝峰 mman 交互 讀書 接受 ogr 大小 C#本質論第一章。 語言規範 要更註重標識符的清晰而不是簡短。 不要在標識符名稱中使用單詞縮寫。 不要使用不被廣泛接受的首字母縮寫詞,即使被廣泛接受,非必要時也不要用。 要把只含兩個字母的首字母縮寫詞
【讀書筆記】C#本質論第二章
否則 TE 引用 字節 字符類 oid 情況 情況下 pat C#本質論第二章。 基本數據類型 C#的基本數據類型包括整型,浮點類型以及decimal的特殊浮點類型。 整數類型 C#的所有基本類型都有短名稱和完整名稱,完整名稱對應於基類庫(Base Class Libr