java反射头文件_编程基础知识——C++能不能支持Java和ObjC的反射?
C++能不能支持Java和ObjC的反射?
要回答這個問題。首先我們要清楚什么是反射。什么是反射?
教科書的解釋我就不說了,(^o^)事實上我也記不得。實際開發應用的反射就是在沒有某個類型的頭文件或者類結構定義的情況下,存取這個類型的對象的成員字段的值。調用這個對象的成員函數(方法)。
比方我有定義了一個類型 Class ?A,里面有 a,b,c三個字段,有fun()函數。
如今我手里僅僅有一個 void* pA,注意它的類型僅僅是一個void指針,我手里也沒有Class的頭文件。我要怎么樣得到,a,b。c的值呢?怎么調用fun函數呢?另一種需求就是通過字符串運行代碼。比方已經拿到了一A的對象pA了,還拿到了一個字符串 "pA->fun()",如今怎么樣才干將這個字符串代表的代碼。運行了呢?(后面這樣的需求最典型的需求就是表達式引擎)。以上說的就是反射的用處和優點,非常多實際需求中使用起來是非常非常方便的,能夠在非常多場合節省非常多時間,少寫非常多代碼。
眾所周知。Java和ObjC支持反射。當然還有其它語言也支持,本人知識水平有限。不能全然列舉還請見諒。
假設要實現反射,就須要實現例如以下幾個功能:
拿到一個對象指針。哪怕它是void。也能通過一些API,得到它的真實類類型名稱。比方java能夠得到它的實際類型的包路徑+類名
拿到這個對象指針,還能得到它全部的成員變量。成員函數的名稱,類型(字段),參數和返回類型(函數),以字符串或者其它封裝類型返回。核心還是字符串。
拿到這個對象指針,能夠通過字符串。運行某個函數。能夠通過字符串,取得某個成員的值。
Java和ObjC都能支持反射,另一個前提是由于他們都統一基類。比方java里叫 java.lang.Object 。ObjC里面是 NSObject。有了統一基類,才可以預先定義一套反射的機制和API。不論什么繼承這個基類的實現類,都附帶贈送了早已實現的反射功能。
而C++沒有標準基類,各種框架,各種平臺有各種各樣的框架,類庫。
如果我們自己在實際開發的系統里面,定義一個統一基類,是不是能在C++里面。實現反射功能,哪怕是別扭的實現也好啊,這樣也能夠降低非常多苦逼C++開發者的工作量的呀,多好的事啊。
試試吧
首先我們如果應用程序里面的全部類。都有一個公共基類。
其次C++里面的成員變量,成員函數,對象,全部一切,都是指針定位。
所以我們先要解決,通過“一個對象指針 + 一個函數指針調用函數的問題”。
完整演示程序已經寫好了
#include "stdafx.h"
class CXObject
{
public:
int doSum(int a, int b);
};
typedef int (CXObject::*pf_doSum)(int, int);
int CXObject::doSum(int a, int b)
{
return a + b ;
}
void dosome(CXObject* pObj, pf_doSum func)
{
int result = (pObj->*func)(100, 23);
printf("result=%d", result);
}
int _tmain(int argc, _TCHAR* argv[])
{
CXObject obj ;
dosome(&obj, &CXObject::doSum);
getchar();
return 0;
}
能夠看到,能夠通過一個對象指針,加一個函數指針 調用函數。
這是C++里面也算是非經常常使用的技巧了。
MFC里面系統生成的代碼非常多都是用這樣的方式。
我們的需求是通過字符串,調用函數,所以就須要建立一個 函數名稱 到 函數指針的映射關系。然后就能夠字符串查找 函數指針,函數指針調用函數了。
請看完整代碼:
// test01.cpp : 定義控制臺應用程序的入口點。
//
#include "stdafx.h"
#include
#include
class CXObject ;
typedef void (CXObject::*void_func_void)(void);
class CXObject
{
public:
//取得類的全部函數的名稱
virtual void getMethodNames(std::vector<:string>& names);
//依據名稱,取得函數指針
virtual void_func_void getFuncByName(std::string& name);
};
void CXObject::getMethodNames(std::vector<:string>& names){}
void_func_void CXObject::getFuncByName(std::string& name){return NULL;}
class CXMyImpl : public CXObject
{
public: //須要實現的函數
//取得類的全部函數的名稱
virtual void getMethodNames(std::vector<:string>& names);
//依據名稱,取得函數指針
virtual void_func_void getFuncByName(std::string& name);
public://自定義的業務函數。
void doPrint1();
void doPrint2();
};
void CXMyImpl::getMethodNames(std::vector<:string>& names)
{
names.push_back("doPrint1");
names.push_back("doPrint2");
}
void_func_void CXMyImpl::getFuncByName(std::string& name)
{
void_func_void pFun = NULL ;
if(name.compare("doPrint1") == 0)
pFun = static_cast(&CXMyImpl::doPrint1) ;
if(name.compare("doPrint2") == 0)
pFun = static_cast(&CXMyImpl::doPrint2) ;
return pFun ;
}
void CXMyImpl::doPrint1()
{
printf("CXMyImpl::doPrint1 be called!!\r\n");
}
void CXMyImpl::doPrint2()
{
printf("CXMyImpl::doPrint2 be called!!\r\n");
}
int _tmain(int argc, _TCHAR* argv[])
{
CXObject* obj = new CXMyImpl();
//后面的代碼里,并沒有CXMyImpl,CXObject里面未定義doPrint1,doPrint2.
//通過字符串的doPrint1運行doPrint1函數。
std::vector<:string> names ;
obj->getMethodNames(names);
for(int idx=0; idx
{
void_func_void pfun = obj->getFuncByName(names[idx]);
(obj->*pfun)();
}
getchar();
return 0;
}
執行結果例如以下:
從上面的樣例能夠看到,事實上是能夠模擬出反射的效果的。
假設要C++全然的實現方便有用的反射機制,須要下面幾點條件:
1、統一的基類
2、編譯器要幫忙
對于第二條條件,能夠這樣理解:
在上樣例中
void CXMyImpl::getMethodNames(std::vector<:string>& names)
{
names.push_back("doPrint1");
names.push_back("doPrint2");
}
void_func_void CXMyImpl::getFuncByName(std::string& name)
{
void_func_void pFun = NULL ;
if(name.compare("doPrint1") == 0)
pFun = static_cast(&CXMyImpl::doPrint1) ;
if(name.compare("doPrint2") == 0)
pFun = static_cast(&CXMyImpl::doPrint2) ;
return pFun ;
}
這兩個函數是基類里面定義好了的,算是反射相關的API,可是假設我每寫一個類都要自己實現這兩個函數。那豈不是要累死。
可是反過來看,這兩個函數的功能很easy,代碼很有規律。那就是記錄當前的類有那些函數,把名字和函數指針相應起來。這個過程全然能夠讓編譯器在編譯的時候自己主動為我加上。
還有一方面,因為為了方便演示。這里面用到的業務函數都是 void f(void)類型的。沒有參數和返回值,這樣顯然是不合理的。可是并非不能實現,僅僅只是那樣更復雜。繞的圈子很多其它。
在沒有這種編譯器出現,在沒有這種統一基類的類庫的情況下,C++的反射,僅僅是停留在興趣調研的階段,眼下沒看到什么實際價值。個人感覺的哈。
總結
以上是生活随笔為你收集整理的java反射头文件_编程基础知识——C++能不能支持Java和ObjC的反射?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 谷歌浏览器开发调试工具中Sources面
- 下一篇: JSP+Javabean+Servlet