簡單的說,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; }
 
沒有留言:
張貼留言