65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.86/5 (4投票s)

2015 年 6 月 12 日

CPOL

1分钟阅读

viewsIcon

17660

downloadIcon

111

是的!使用手动编写的反射类。提供了示例代码。

引言

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 方法。我会再考虑一下。感谢阅读。

本文最初发表于

© . All rights reserved.