1. 程式人生 > >用C++實現簡單的反射機制

用C++實現簡單的反射機制

備忘記錄下來。

程式碼如下:

巨集定義REGISTER解讀:
這個巨集做了兩件事情,
第一件事情是聲明瞭一個函式,即 className* objectCreator##className();
宣告的這個函式,每有一個類需要註冊,就會配套著有一個new出待註冊類的函式。這些個函式有一致的格式:
無引數,返回型別為該類的指標(可以強轉為void*)。

第二件事情是聲明瞭一個物件,即 RegisterAction g_creatorRegister##className(xxx,yyy);
這個RegisterAction建構函式有兩個引數,第一個引數string是類的名字,第二個引數PTRCreateObject
是一個函式指標,指向上面第一步宣告的那個函式。

在做第二件事情時,也即RegisterAction的建構函式,會將它的兩個引數分別當作key和value,插入到
ClassFactory::m_classMap當中,這也就是ClassFactory::getInstance().registClass(className, ptrCreateFn);
這句程式碼的真正用途。

當然啦,第二件事情宣告的這個物件是位於靜態儲存區的,它會在main函式之前就被構造出來。
#include <map>
#include <iostream>
#include <string>

using namespace std;

typedef void* (*PTRCreateObject)(void);


class ClassFactory {
private:
    map<string, PTRCreateObject> m_classMap;
    ClassFactory() {}; //建構函式私有化

public:
    void* getClassByName(string className);
    void registClass(string name, PTRCreateObject method);
    static ClassFactory& getInstance();
};


void* ClassFactory::getClassByName(string className) {
    map<string, PTRCreateObject>::const_iterator iter;
    iter = m_classMap.find(className);
    if (iter == m_classMap.end())
        return NULL;
    else
        return iter->second();//返回的是PTRCreateObject型別的函式指標,可以轉化為void*
}

void ClassFactory::registClass(string name, PTRCreateObject method) {
    m_classMap.insert(pair<string, PTRCreateObject>(name, method));
}

ClassFactory& ClassFactory::getInstance() {
    static ClassFactory sLo_factory;
    return sLo_factory;
}

class RegisterAction {
public:
    RegisterAction(string className, PTRCreateObject ptrCreateFn) {
        ClassFactory::getInstance().registClass(className, ptrCreateFn);
    }
};

#define REGISTER(className)                                             \
    className* objectCreator##className(){                              \
        return new className;                                           \
    }                                                                   \
    RegisterAction g_creatorRegister##className(                        \
        #className,(PTRCreateObject)objectCreator##className)

//test class
class TestClass {
public:
    void m_print() {
        cout << "hello TestClass" << endl;
    };
};
REGISTER(TestClass);

void test_register_class()
{
    TestClass* ptrObj = (TestClass*)ClassFactory::getInstance().getClassByName("TestClass");
    ptrObj->m_print();

    return ;
}

相關推薦

C++實現簡單反射機制

備忘記錄下來。 程式碼如下: 巨集定義REGISTER解讀: 這個巨集做了兩件事情, 第一件事情是聲明瞭一個函式,即 className* objectCreator##classNam

C++實現簡單的檔案I/O操作

檔案 I/O 在C++中比烤蛋糕簡單多了。 在這篇文章裡,我會詳細解釋ASCII和二進位制檔案的輸入輸出的每個細節,值得注意的是,所有這些都是用C++完成的。 一、ASCII 輸出 為了使用下面的方法, 你必須包含標頭檔案<fstream.h>(譯者注:在標準C++中,已

c#實現簡單文字編譯器

上學期有個程式設計實驗,其中一個是需要實現一個帶介面的簡單文字編輯器。這裡選擇用c#來實現。 頁面設計和具體功能 在檔案處選擇新建一個文字,這裡的文字使用窗體實現載入 有一些快捷鍵:比如字型選擇按鈕,點選以後可以出現一個窗體,實現字型的選擇。但是這裡貌似有點

C++實現簡單執行緒池

執行緒池 什麼是執行緒池 在使用執行緒的CS模型中,伺服器端每接收到一個客戶端請求,都會為客戶端建立執行緒資源,當有大量突發性請求時,伺服器來不及為每個客戶端建立執行緒。執行緒每次的建立與銷燬都會耗費伺服器大量資源與時間,可以在伺服器一開始就建立好一堆執行緒,等到客戶端請求來

c#實現簡單的登入和註冊功能

      這兩天c#大作業要求做一個簡單的通訊錄系統,我就先做了登入和註冊的功能,在網上看了一些程式碼,自己再做,終於做出來了。做的不是很美觀,但是可以簡單實現。    首先用sqlserver建表。我建了一個名為user_info的表,新增username和passdwo

C#實現簡單的帶有驗證碼及密碼使用MD5加密的“登入”WinForm小程式

初學C#Windows窗體程式時,做個簡單的“登入”是再簡單不過的了。像下面這樣的,功能稍理想了吧? 有後臺數據庫,有驗證碼,資料庫中密碼是密文(如圖所示:資料庫中表資料是32位MD5加密的……) 下面講解如何實現。 步驟: 1、建立相應的資料

C# 實現一個簡單的 Rest Service 供外部調

message [] operation rem adk www span method title 用 C# 實現一個簡單的 Restful Service 供外部調用,大體總結為4點: The service contract (the methods it o

C++實現七種排序演算法,可選擇排序方法,簡單易懂。

       最近學習演算法,先從簡答的開始學起,用C++做了一個實現七種排序演算法的介面,可選擇想要用的選擇演算法,不過,由於時間倉促,沒有來得及優化和程式碼註釋,後期還會加上程式碼註釋,隨便優化一下程式碼,提高執行效率; /***********************

C/C++實現簡單的單向列表

用C/C++實現單向列表建立與輸出連結串列儲存值的操作 // 連結串列.cpp : 定義控制檯應用程式的入口點。 // #include "stdafx.h" #include <iostream> using namespace std; //建立一個連結

VS下C++實現簡單3D射擊遊戲(附遊戲檔案與源工程程式碼)

記不得什麼時候開始感興趣寫遊戲程式碼了。開始的時候就只是寫一些簡單的小遊戲,打檯球,開小車,走迷宮,用一些2Dgraphics庫,完成每個小作品後都很開心。後來一想,在現在的計算機裝置條件下,2D太簡陋了,於是開始著手做一個3D賽車遊戲。說是賽車,實際上也就只有一輛小車。模

C++實現約瑟夫環的問題

content 人在 -h tel padding next family bsp sun 約瑟夫問題是個有名的問題:N個人圍成一圈。從第一個開始報數,第M個將被殺掉,最後剩下一個,其余人都將被殺掉。比如N=6,M=5。被殺掉的人的序號為5,4,6。2。3。最後剩下1

c++實現高精度加法

strlen 數位 cout col 代碼 code pre 操作數 eof c++實習高精度加法 最近遇到一個c++實現高精度加法的問題,高精度問題往往十復雜但發現其中的規律後發現並沒有那麽復雜,這裏我實現了一個整數的高精度加法,主要需要註意以下幾點: 1:將所需

jQuery實現簡單的DOM操作

追加 匹配 簡單的 rep 兄弟節點 子元素 spa 添加元素 新建 通過jQuery創建元素節點:$oLi = $("<li></li>");這樣我們就創建了一個li標簽 如果想在元素節點中添加文本的話也挺簡單:$oLi = $("<li&g

c實現的各種排序的方法

else print switch %d [] code article 選擇 ++ #include <stdio.h> void swap(int *a, int *b); void bubble_sort(int a[], int n); void

C++實現簡單的文本查詢

ber number map () first begin ifstream adf times 1 該程序將讀取用戶指定的任意文本文件,然後允許用戶從該文件中查找單詞。查詢的結果是該單詞出現的次數,並列出每次出現所在的行。如果某單詞在同一行中多次出現,程序將只顯示該

jq實現簡單輪播

cti 標簽 function radi har mil ott ava 懸停 一個簡單的實例: css代碼: <style type="text/css">@charset "utf-8";*{ padding:0px; border:

javascript實現簡單戶登錄驗證

-c turn get https 沒有 驗證 utf-8 .com head 1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="

C/C++】:C實現輸出日期的陰歷日子

print http this while lunar void 大小 oid pan 前言 輸出陰歷一直是個老大難的問題。由於陰歷日子沒有規律。所以這裏須要做的就是通過打表的算法做到輸出陰歷日子,可是非常多人都不太了解原理,我這裏就給大家送上了一個福

C#實現簡單的Http請求實例

semaphore bsp .text block 通過 renren www 字節 req 本文實例講述了C#實現簡單的Http請求的方法。分享給大家供大家參考。具體分析如下: 通過.Net中的兩個類HttpWebRequest類,HttpWebResponse類來實現

【SSH學習筆記】Struts2實現簡單戶登錄

utf-8 png rds href -a his ets 屬性 url 準備階段 在使用學習Struts2的時候首先要下載相應的架包 Struts2資源下載 這裏建議下載第一個,在struts-2.5.14.1-all.zip裏有很多實用的東西,不僅有架包還有官方為開發