Having programmed mostly in C# I find myself in a loss when it comes to C++. I however need to create a C++ app, as it is merely a component in a bigger C++ solution.
Situation
- I have a struct (Parent) that include a data component (object). This could be a data component of any type - i.e. custom struct too.
- Only the compiler of the Parent (who created the Parent incl object), and the end receiver needs to know the type of the data component inside the object, as the data is only relevant to them.
- The Parent struct however might pass through several methods, objects and even to other processes.
- The data options for the object are limited, and both compiler and decompiler knows the different options of data types.. hence they are able to decompile the object in original form
- The types however could be extended (i.e. though limited it is not necessarily fixed) and the decompiler and compilers updated in future
Problem - I do not want to recreate each method and object that might encounter this data component with a "template"... also seeing that the data type could in future be altered suggested that templates for each process that encounter the object in the long run is not ideal to start with.
I was looking for something similar to C# Object - and have written the following components
Question
- Is this a good solution or may I encounter problems in the future
- Is there an improvement that could be made on this? That I have not thought about (especially for not including the Object\impl.h?
- Is there a totally different / better solution?
The Code
I have the following in my Header file
struct Object { Object(); // Return true if value has succesfully been set // Return false if there is no compatibility between Value and result. template <typename T> bool GetValue(T &result); template<typename T> bool SetValue(T value); virtual LPVOID GetObjectAddress() = 0; virtual const char* GetType() = 0; }; template<typename T> struct ObjectType:public Object { ObjectType(T value); T Value; LPVOID GetObjectAddress(); const char* GetType(); };
I also have have a CreateType function for creating several ready made objects at start and for example purposes is called as follows at end of .h file
template class CreateType<int>;
Bear in mind the int is just for example... it is actually different structs.
I also have another header file which is included at the bottom of this header file as follows:
#include "Implementation\Object_impl.h" -> looks like this template<typename T> ObjectType<T>::ObjectType(T value) { Value = value; }; template <typename T> // Return true if value has succesfully been set // Return false if there is no compatibility between Value and result. bool Object::GetValue(T &result) { if (typeid(result).name() == GetType()) { result = *(T *)GetObjectAddress(); return true; } return false; }; template<typename T> bool Object::SetValue(T value) { if (typeid(T).name() == GetType()) { *(T*)GetObjectAddress() = value; return true; } return false; }; template<typename T> const char* ObjectType<T>::GetType() { return typeid(Value).name(); } template<typename T> EXPOBJ LPVOID ObjectType<T>::GetObjectAddress(){ return (LPVOID)&Value; }
I wish I could include most of this in a cpp file, but then I would not be able to create different object on demand... I am not yet sure what the implications would be... also to extend the types one only need to include the normal object header file.
I know inline could be an option, but also think it is not ideal?
At the moment however this compiles and works perfectly as a "generic" option. One could also extend by inheriting from inheriting from "Object"?
...oh and to use I just do this - which seemed to work:
Object * a;
a = new ObjectType<testing>(testing());
testing x = testing();
x.i = 50;
a->SetValue(x);
testing y = testing();
testing &z = y;
a->GetValue(z);
cout << z.i << " for z and y = " << y.i << endl;
Result -> 50 for z and y = 50