[源碼下載]
作者: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
[源碼下載]