[源碼下載]
作者:webabcd
介紹
不可或缺 Windows Native 之 C++
示例
1、基類
CppHuman.h
#pragma once #include <string> using namespace std; namespace NativeDll { class CppHuman { protected: string Name; public: // 我是虛函數 virtual string Show(); // 我是純虛函數(後面的“=0”只起形式上的作用,用於告訴編譯器:“這是純虛函數”) // 純虛函數只有聲明,沒有定義,其具體的功能是留給派生類定義的 // 凡是包含純虛函數的類都是抽象類,抽象類是無法實例化的,因為純虛函數是不能被調用的 // virtual string Display() = 0; CppHuman(string name); // 我是 virtual 的析構函數 virtual ~CppHuman(); }; }
CppHuman.cpp
/* * 基類 */ #include "pch.h" #include "CppHuman.h" #include "cppHelper.h" using namespace NativeDll; string CppHuman::Show() { return "human: " + Name; } CppHuman::CppHuman(string name) : Name(name) { } CppHuman::~CppHuman() { }
2、派生類
CppChild.h
#pragma once #include <string> #include "CppHuman.h" using namespace std; namespace NativeDll { class CppChild : public CppHuman { public: // 由於基類 CppHuman 的 Show() 函數是虛函數,所以其所有直接或間接派生類中,如果聲明了此函數則均為虛函數(virtual 可以省略) virtual string Show(); CppChild(string name); ~CppChild(); }; }
CppChild.cpp
/* * 派生類(基類是 CppHuman) */ #include "pch.h" #include "CppChild.h" #include "cppHelper.h" using namespace NativeDll; string CppChild::Show() { return "child: " + Name; } CppChild::CppChild(string name) : CppHuman(name) { } CppChild::~CppChild() { }
3、示例
CppClass7.h
#pragma once #include <string> using namespace std; namespace NativeDll { class CppClass7 { public: string Demo(); }; }
CppClass7.cpp
/* * 虛函數 */ #include "pch.h" #include "CppClass7.h" #include "CppChild.h" using namespace NativeDll; void cppclass7_demo1(); void cppclass7_demo2(); string CppClass7::Demo() { // 虛函數 cppclass7_demo1(); // virtual 的析構函數 cppclass7_demo2(); return "看代碼及注釋吧"; } // 虛函數 void cppclass7_demo1() { // 不使用虛函數的示例:參見 CppClass5.cpp 中的“基類與派生類的轉換” // 以下演示了如何使用虛基類 CppHuman human("webabcd"); CppChild child("diandian"); // 指針指向基類,調用虛函數後執行的是基類的虛函數 CppHuman *humanPointer = &human; string result = humanPointer->Show(); // human: webabcd // 指向基類的指針改為指向派生類,調用虛函數後執行的是派生類的虛函數 humanPointer = &child; result = humanPointer->Show(); // child: diandian // 像上面這種方式是在程序運行階段把虛函數和類對象“綁定”在一起的,因此此過程稱為動態關聯(dynamic binding)或滯後關聯(late binding),其屬於動態多態性 // 如果使用了虛函數,則編譯器會為該類構造一個虛函數表(virtual function table,簡稱 vtable),它是一個指針數組,存放每個虛函數的入口地址,據此可做靜態關聯和動態關聯 } // virtual 的析構函數 void cppclass7_demo2() { // 一般來說,清理派生類時,會先調用派生類的析構函數,然後調用基類的析構函數 // 但是下面這種情況例外 CppHuman *pt = new CppChild("diandian"); delete pt; // 此時,如果基類的析構函數不是 virtual 的,則只會執行基類的析構函數 // 此時,如果基類的析構函數是 virtual 的,則會先執行派生類的析構函數,再執行基類的析構函數 // 所以,最好把基類的析構函數聲明為虛函數(其會使所有派生類的析構函數都自動變為虛函數),以避免清理不徹底 }
OK
[源碼下載]