我希望能够自省一个c++类的名称,内容(即成员及其类型)等。这里我说的是原生c++,而不是托管c++,托管c++有反射。我意识到c++使用RTTI提供了一些有限的信息。哪些附加库(或其他技术)可以提供这些信息?
当前回答
我想你可能会对Dominic Filion写的“在c++中使用反射模板”这篇文章感兴趣。它在Game Programming Gems 5的1.4部分。不幸的是,我没有带我的副本,但你可以找找看,因为我认为它解释了你想要的东西。
其他回答
编辑:不再维护CAMP;有两个fork可供选择:
其中一个也被称为CAMP,并且基于相同的API。 思考是部分重写,应该优先考虑,因为它不需要Boost;它使用c++ 11。
CAMP是MIT授权的库(以前是LGPL),它向c++语言添加了反射。它在编译中不需要特定的预处理步骤,但是必须手动进行绑定。
目前的Tegesoft库使用Boost,但也有一个使用c++ 11的分支不再需要Boost。
如果你像这样声明一个指向函数的指针:
int (*func)(int a, int b);
您可以像这样在内存中为该函数分配一个位置(需要libdl和dlopen)
#include <dlfcn.h>
int main(void)
{
void *handle;
char *func_name = "bla_bla_bla";
handle = dlopen("foo.so", RTLD_LAZY);
*(void **)(&func) = dlsym(handle, func_name);
return func(1,2);
}
要使用间接方式加载局部符号,可以对调用二进制文件(argv[0])使用dlopen。
这样做的唯一要求(除了dlopen()、libdl和dlfcn.h)是知道函数的参数和类型。
周围有两种反射。
Inspection by iterating over members of a type, enumerating its methods and so on. This is not possible with C++. Inspection by checking whether a class-type (class, struct, union) has a method or nested type, is derived from another particular type. This kind of thing is possible with C++ using template-tricks. Use boost::type_traits for many things (like checking whether a type is integral). For checking for the existence of a member function, use Templated check for the existence of a class member function? . For checking whether a certain nested type exists, use plain SFINAE .
如果你想要实现1),比如查看一个类有多少个方法,或者获取一个类id的字符串表示形式,那么恐怕标准c++没有办法做到这一点。你必须使用其中任何一个
一个元编译器,如Qt元对象编译器,它翻译你的代码,添加额外的元信息。 由宏组成的框架,允许您添加所需的元信息。你需要告诉框架所有的方法、类名、基类和它需要的一切。
c++的设计考虑到了速度。如果您想要高级别的检查,就像c#或Java所做的那样,不做一些额外的工作就无法做到这一点。
尽管在c++中不支持即时可用的反射,但实现它并不太难。 我遇到了这篇很棒的文章: http://replicaisland.blogspot.co.il/2010/11/building-reflective-object-system-in-c.html
本文详细介绍了如何实现一个非常简单的反射系统。当然,这不是最有益的解决办法,还有一些粗糙的地方有待解决,但对我的需要来说,这已经足够了。
底线——如果做得正确,反射是可以得到回报的,而且在c++中是完全可行的。
Ponder是一个c++反射库,用于回答这个问题。我考虑了这些选择,决定自己做一个,因为我找不到一个符合我所有要求的。
虽然这个问题有很好的答案,但我不想使用大量宏,也不想依赖Boost。Boost是一个很棒的库,但也有很多小型定制的c++ 0x项目,它们更简单,编译时间更快。能够从外部装饰一个类也有好处,比如包装一个不支持c++ 11的c++库。它是CAMP的分支,使用c++ 11,不再需要Boost。
推荐文章
- decltype(auto)的一些用途是什么?
- Shared_ptr转换为数组:应该使用它吗?
- Printf与std::字符串?
- 禁用复制构造函数
- 只接受特定类型的c++模板
- c#和Java中的泛型有什么不同?和模板在c++ ?
- 即使模板文件存在,Flask也会引发TemplateNotFound错误
- c++ 11中的递归lambda函数
- 在c++中指针使用NULL或0(零)吗?
- 在c++中,如何将int值附加到字符串中?
- 就性能而言,使用std::memcpy()还是std::copy()更好?
- 为什么布尔值是1字节而不是1位?
- 四舍五入到一个数字的最接近倍数
- jQuery模板引擎
- 模板默认参数