你能将对象序列化到 C++ 并从 C++ 反序列化吗?






4.86/5 (4投票s)
是的!使用手动编写的反射类。提供了示例代码。
引言
C++ 缺乏丰富的反射机制 - 因此你必须自己编写或使用像 Boost 提供的库。我一直在思考这个想法一段时间了,我认为我知道该如何实现它。你首先要追求的是简洁性 - 这是我对反射类可能的样子的一个想法。假设你有一个类 'AClass
',并且你想对其进行反射。
示例类和反射存根
class AClass
{
public:
int aValue;
int anotherValue;
std::string thirdValue;
};
class AClass2
{
public:
std::string testing;
std::string testing2;
};
template<typename T>
class ClassDescriptor
{
};
template<>
class ClassDescriptor<AClass>
{
public:
template<typename TCallback>
void for_each_property(const TCallback& callback)
{
callback("aValue", &AClass::aValue);
callback("anotherValue", &AClass::anotherValue);
callback("thirdValue", &AClass::thirdValue);
}
};
template<>
class ClassDescriptor<AClass2>
{
public:
template<typename TCallback>
void for_each_property(const TCallback& callback)
{
callback("testing", &AClass2::testing);
callback("testing2", &AClass2::testing2);
}
};
template<typename TClass>
ClassDescriptor<TClass> GetClassDescriptor(TClass& t)
{
return ClassDescriptor<TClass>();
}
示例算法
模板特化允许你表示你感兴趣的任何类类型,并且可以捕获该类中每个属性的偏移量。然后,你只需要表示该算法即可。
template<typename TClass>
class SamplePropertyAlgorithm
{
TClass& m_t;
public:
SamplePropertyAlgorithm(TClass& t):m_t(t)
{
}
template<typename TPropertyType>
void operator()(const char* szProperty,
TPropertyType TClass::*pPropertyOffset) const
{
std::cout << szProperty << ": " << m_t.*pPropertyOffset << std::endl;
std::cout << "enter new value:" << m_t.*pPropertyOffset;
std::cout << szProperty << ": " << m_t.*pPropertyOffset << std::endl;
}
};
template<typename T>
void RunAlgorithm(T& t)
{
GetClassDescriptor(t).for_each_property(SamplePropertyAlgorithm<T>(t));
}
哇!说了很多,但你只需要为每个属性编写一次,并且你不仅捕获了名称,还捕获了每个属性的类型和值。
示例用法
为了说明,以下是使用方法
int main(int argc, const char * argv[])
{
AClass c1;
c1.aValue = 1;
c1.anotherValue = 2;
c1.thirdValue = "this is a test";
AClass2 c2;
c2.testing = "ABC";
c2.testing2 = "DEF";
RunAlgorithm(c1);
RunAlgorithm(c2);
return 0;
}
示例交互
这是与程序的示例交互
aValue: 1
enter new value:2
aValue: 2
anotherValue: 2
enter new value:3
anotherValue: 3
thirdValue: this is a test
enter new value:test
thirdValue: test
testing: ABC
enter new value:EEE
testing: EEE
testing2: DEF
enter new value:FF
testing2: FF
就这样。我相信你可以使用预处理器使它更简洁,并进一步抽象它,允许更多类型的属性 - 例如 getter 和 setter 方法。我会再考虑一下。感谢阅读。
本文最初发表于