Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C++

Can You Serialize Objects to and from C++?

4.86/5 (4 votes)
12 Jun 2015CPOL1 min read 17.4K   88  
Yes! Using a hand coded reflection class. Sample code provided.

Introduction

C++ lacks a rich reflection mechanism - so you have to write your own or use a library like the one that boost provides. I've been toying with this idea for quite a while and I think that I have an idea of how you would do this. The very first thing you would aim for is brevity - here's my idea of what a reflection class could look like. Imagine you have a class 'AClass' and you want to reflect it.

Sample Classes and Reflection Stub

C++
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>();
}

Sample Algorithm

A template specialisation allows you to represent any class type that you're interested in and you can capture the offset for each of the properties of that represented class. Then, all you need to do is represent the algorithm:

C++
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));
}

Wow! That was a mouthful, but you only have to write it once, for each property, and you've captured not only the name but the type and value of each property.

Sample Usage

For illustration, here is the usage:

C++
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;
}

Sample Interaction

And here is a sample interaction with the program:

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

There you have it. I'm sure you can make this briefer using the preprocessor, and abstract it further allowing more kinds of properties - such as getter and setter methods. I'll think it over. Thanks for reading.

This article was originally posted at:

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)