簡單的說,header only 是把一個 class 的程式碼就包含在這個 class 中,而這個 class 就放在引入檔(.h)中供大家使用。有別於引入檔只放 class 介面,程式碼則放在 .cpp 中。
header only 的好處是執行快,因一大部份的函數可以用 inline 的方式呼叫,另外也不用再加 .cpp 或是還要連結程式庫(lib 或 dll)。
但有一個不得不面對的問題,class 的程式碼因不放在特定的 .cpp 中,那麼使用它的模組(exe、lib、dll)都得編譯出各別的執行碼,一般來說除了程式會比較胖之外,也沒有其它不好的影響。但是遇到插件就出問題了。
插件是一個 dll 檔,特點是要用的時候才載入,不用的時候可以卸載,但若某一個 class 產生的物件,其執行碼在那個被卸載的 dll 中,就會出大問題了,以下範例程式就是在演示這種情況。
/* ** test.h : header only 形式的引入檔 */
class Test { const char Str[20]{ "I am Test" }; public: Test() { } ~Test() {};
// inline const char *GetStr1() const { return Str; }
// 迫使使用端一定得使用服務端提供的實作碼 virtual const char *GetStr2() const { return Str; } };
/* ** dllmain.cpp : 定義 DLL 應用程式的進入點。 */
#include "test.h"
extern "C" __declspec(dllexport) Test *__cdecl GetTest() { return new Test; }
/* ** customer.cpp: 定義主控台應用程式的進入點。 */
#include <Windows.h> #include <test.h> #include <iostream>
using namespace std;
HINSTANCE DLLInst; Test*(__cdecl *GetTest)();
int main() {
DLLInst = LoadLibraryW(L"Server.dll"); GetTest = (decltype(GetTest))GetProcAddress(DLLInst, "GetTest");
Test *pTest = GetTest(); const char *Str1; const char *Str2;
Str1 = pTest->GetStr1(); cout << "Str1: " << Str1 << endl; Str2 = pTest->GetStr2(); cout << "Str2: " << Str2 << endl;
FreeLibrary(DLLInst);
Str1 = pTest->GetStr1(); cout << "Str1: " << Str1 << endl; Str2 = pTest->GetStr2(); cout << "Str2: " << Str2 << endl;
return 0; }
沒有留言:
張貼留言