C++ 如何遍历类中的所有成员?
C++ 如何遍历类中的所有成员?,c++,C++,假设我有一节课 class CAT { private: int a; long b; double c; string d; }; 现在我需要一个可以将所有成员初始化为特定值的函数,例如: int设置为0 长时间设置为-1 双重设置为-1.1 字符串设置为未知 到目前为止,我可以编写一个名为initMembers的函数: void initMembers() { a = 0; b = -1;
假设我有一节课
class CAT
{
private:
int a;
long b;
double c;
string d;
};
现在我需要一个可以将所有成员初始化为特定值的函数,例如:
- int设置为0
- 长时间设置为-1
- 双重设置为-1.1
- 字符串设置为未知
void initMembers()
{
a = 0;
b = -1;
c = -1.1;
d = "unknown";
}
但是如果我有1000个像CAT这样的类,其中一些有4个成员,一些有40个成员,。。。。。所以我必须为每个类编写initMember函数
我想知道是否有方法可以遍历类中的所有成员
谢谢你的帮助
我的意思是我想用一个对应的值初始化特定的类型
适用于所有类中的所有成员
< C++ >没有反射。 < P>我可以给你推荐一本C++书吗?我认为你缺少了这门语言的一些基本知识
initMembers()函数中执行的操作:
class CAT
{
public:
CAT(): a(0), b(-1), c(-1.1), d("unknown") { }
private:
int a;
long b;
double c;
string d;
};
我们在代码中使用了一个hack来自动初始化代码中的数据成员:
#define member(type, name, initval)
class class_ ## name { \
type data;
inline class_ ## name() : data(initval) {};\
inline type operator()() const { return data; };\
inline void operator(type newval) { data=newval; };\
};
然后,在任何类别中:
class CAT {
private:
member(int, a, 0);
member(long, b, -1);
member(double, c, -1.1);
member(string, d, "unknown");
void foo() {
d("newstring"); // set
int aval=a(); // access
};
};
您可以调整上述宏,并添加一些其他简洁的功能。但是,对于现有代码来说,这意味着需要进行一定程度的重新构造/重写。只是一个关于如何使用以下代码的想法:
正如所有答案所说的,C++中没有反射。如果您有1000个唯一类(不是实例),那么必须编写相同的锅炉板代码(例如CTOR/DTOR,可能是流操作等)是一件痛苦的事情 当我面对这样的事情时,我总是退后一步。首先,不是蒸头,写出每个类的所有C++代码,而是创建一个XML文档,它具有所有的结构,例如,我有两个结构,我将创建一些类似:
<classet>
<struct name="some_struct_a">
<field type="int" name="foo"/>
<field type="int" name="foo2"/>
<field type="long" name="bar"/>
<field type="std::string" name="bar2"/>
</struct>
<struct name="some_struct_b">
<field type="int" name="foo"/>
<field type="int" name="foo2"/>
</struct>
</classet>
一旦完成,我创建XSLT(并且您不需要成为XSL下一级Guru来做这件事),以从上面的XML生成C++代码。因此,如果需要向所有类添加任何方法,例如,修改xsl并重新生成,修改任何结构、修改xml并重新生成也是如此。一旦准备好xml和xslt,更改周期就会非常快
顺便说一句,在你嘲笑之前,很多交易所(金融)提供了描述消息格式的xml文档,正是出于这个原因,其中一些以xml定义了大量消息,有些成员有非常多的成员。 < P>你可能想建立一个源代码生成工具,它把一些你需要的类的数据文档翻译成C++类声明代码。
例如,如果你想为每一种动物建立一个类,并且你有一些关于动物的数字文献,那么创建一个定制的工具来解析动物图书,过滤动物名称并从中创建类样板代码。你只是出于好奇而问,或者你真的需要做这样的事情吗?请看这个相关的问题:以及公认的答案——它可能对你有帮助。@sharptooth:但这个问题真的适用吗<代码>-1、
-1.1
和“未知”
都不同于初始化将给您提供的值,并且彼此都不同。我想你可以明确地专门为每一种类型专门编写<代码>初始化的//Cuth>模板。@ Charles Bailey:是的,它部分适用,因为C++没有反射,可以写模板特写,并且用这种方法来解决问题。这不会很好,但会起作用。OP没有说“命名猫”,他说“像猫一样”:)我想做的是用相应的值初始化特定类型。你的意思是,对于一组不同类的对象,你想将每个int初始化为1,每个long初始化为-1等等?一旦你意识到了这一点,C++不提供反射和内省等关键特征,而是使用XML来表示类,你也可以使用它来生成样板代码,以便在GObjad之类的东西中使用它。我做了类似的事情,但在每个成员之后使用了“/=0”之类的注释,然后制作了一个Perl脚本来生成实际的构造函数、getter和setter。
#include <iostream>
#include <string>
#include <boost/fusion/adapted/struct/define_struct.hpp>
#include <boost/fusion/algorithm/iteration/for_each.hpp>
#include <boost/lambda/lambda.hpp>
BOOST_FUSION_DEFINE_STRUCT
(
/* namespace */,
CAT,
(int, a)
(long, b)
(double, c)
(std::string, d)
)
struct initializer
{
void operator()(int &v) const { v = 1; }
void operator()(long &v) const { v = -1; }
void operator()(double &v) const { v = 1.1; }
void operator()(std::string &v) const { v = "unknown"; }
};
int main()
{
CAT c;
boost::fusion::for_each(c, initializer());
boost::fusion::for_each(c, std::cout << boost::lambda::_1 << ' ');
std::cout << std::endl;
}
1 -1 1.1 unknown
<classet>
<struct name="some_struct_a">
<field type="int" name="foo"/>
<field type="int" name="foo2"/>
<field type="long" name="bar"/>
<field type="std::string" name="bar2"/>
</struct>
<struct name="some_struct_b">
<field type="int" name="foo"/>
<field type="int" name="foo2"/>
</struct>
</classet>