I'm writing a custom runtime reflection system to serialize the objects of my application (a game, so game entities).
My reflection framework is really simple, it allows me to reflect data types and attach data members, constructors and member functions to these meta types:
// reflect built-in types
Reflect::Reflect<int>("int");
Reflect::Reflect<float>("float");
Reflect::Reflect<std::string>("string");
// reflect TransformComponent
Reflect::Reflect<TransformComponent>("TransformComponent")
.AddConstructor<>()
.AddDataMember<&TransformComponent::SetPosition, &TransformComponent::GetPosition>("position")
.AddDataMember<&TransformComponent::SetId, &TransformComponent::GetId>("id")
.AddDataMember(&TransformComponent::mName, "name")
.AddDataMember(&TransformComponent::f, "f");
I can use reflected members to set and get data members (which can have attached setters and getters) or to construct instances of reflected types:
Reflect::any transformComponentAny = Reflect::Resolve("TransformComponent")->GetConstructor<>()->NewInstance();
// using reflection to set and get object fields
Reflect::any positionAny = Reflect::Resolve("Vector3D")->GetConstructor<>()->NewInstance();
Reflect::Resolve("Vector3D")->GetDataMember("x")->Set(positionAny, 22.22f);
Reflect::Resolve("Vector3D")->GetDataMember("y")->Set(positionAny, 130.12f);
Reflect::Resolve("Vector3D")->GetDataMember("z")->Set(positionAny, 545.12f);
Reflect::Resolve("TransformComponent")->GetDataMember("f")->Set(transformComponentAny, 0.009f);
Reflect::Resolve("TransformComponent")->GetDataMember("position")->Set(transformComponentAny, positionAny);
Reflect::Resolve("TransformComponent")->GetDataMember("id")->Set(transformComponentAny,32325);
Reflect::Resolve("TransformComponent")->GetDataMember("name")->Set(transformComponentAny, std::string("hey a transform, again..."));
all objects are wrapped inside a class like std::any, which abstract the real object, and mantains a type descriptor of the object type (to perform casts, conversions etc..)
Now, this is all ordinary reflection stuff I guess, what I'm stuck on is how to serialize my objects (which is the whole point of all this stuff).
When I want to serialize a member of an object to a JSON, I can easily retrieve the value, given the type descriptor of the object, the meta data member and the instance of the object:
auto typeDesc = object.GetType(); // get the type descriptor for the object (this is a any object)
for (auto dataMember : typeDesc->GetDataMembers())
{
auto fieldName = dataMember->GetName();
auto fieldType = dataMember->GetType()->GetName();
any field = dataMember->Get(object);
if (fieldType == "int")
json[fieldName] = field.Get<int>();
else if (fieldType == "string")
....
}
what I want is to avoid the explicit check for the runtime type and the cast to the type.
I'd like something like this:
json[fieldName] = field // field is a any, it has no info about type at compile time
and let the meta type perform the necessary cast. I'm able to do it when deserializing from a JSON, since the meta types preserve the compile time type of the data member they represent, while any just keeps a type descriptor of the object it contains (I need to call any.Get<> at compile time with the appropriate type).
Any ideas about how to do it?
If I have a class A which contains a pointer to a class B and a method which takes in input a pointer to class B
class A {
private:
B* attribute;
public:
void method(B* par);
}
how can I describe it in a UML class diagram? Do I have to use *? What kind of composition is it?
In UML it is not as important to show whether it is a pointer or not. Why? Because, you may be using UML describing an OOD for a language without pointers.
Quick answer: from your code, A aggregates B (empty diamond at A class, connecting B with a solid line). That is because there is no destructor that deletes what A.attribute pointer references.
What is really important is to say what is the lifetime of the referenced object. So, for a referenced object (has relationship) that dies when the owner is destroyed, you have to use a solid (filled) diamond. This is called composition. So the owner has to manage the life time of the owned object. One such example is human has hands. The hands do not survive when the human object is destroyed.
When the diamond is not filled (aggregation), then the owner is not responsible to manage the life of the object owned. For example you will not expect to see that the owned object being deleted in the destructor. An employer has a TeamLeadRole, but when the employer is "destroyed" (i.e. left the company) then the TeamLeadRole is still available.
Now, traditionally when you see a filled diamond, you usually (not all the time) will have an object by value. Where when you see an empty diamond you may use reference, or pointer.
If your class uses another class but does not keep instances (or references/pointers) to that class, then you can denote dependency by just a simple line (solid) between the objects. That means there is a relationship is called association.
A plain C++ pointer directly corresponds to a reference property in a UML class diagram, as shown in the following diagram:
Such a reference property expresses a uni-directional (binary) association, as shown in the following diagram:
Notice the "dot" at the B side of the association line. It means that the association end with name "attribute" is owned by class A, which means that it corresponds to the reference property shown in the diagram above (the association can be replaced with the reference property). For more explanation see Chapter 5 of this tutorial.
You cannot use the C++ symbol "*" in the UML class diagram because
it is Cpp-specific, while your diagram should probably be platform-independent;
there is no need to use such a symbol in UML because it's clear that the attribute references B objects;
this symbol has a different meaning in UML (the multiplicity unbounded).
In any case, the relationship between the classes A and B is an association. It may be a composition, if you have the additional semantics of an aggregate-component relationship. Notice that your question should be worded: "What kind of association is it?" instead of "What kind of composition is it?" because composition and aggregation are special types of associations.
There IS the possibility to difference between *, & and [] fields on UML class diagrams. It is named "Type Modifier". The problem is to show it on the diagram for your tool. If you have a diagramming tool, simply draw it at the end as a stereotype of the end. But be careful not to mix it with the multiplicity! If you have a modelling tool, you"ll have to look how to do it.
But notice, that pointer/reference field is supposed to be a default one, so you needn't really specify your case in the class diagram.
If you want to show this information in a correct way, use a more detailed Composite Structure Diagram. There you can show these &,*,[] at you wish.
For different variants of association in class diagram look this my answer for the similar question:
https://stackoverflow.com/a/21478862/715269
boost::serialization is able to serialize my polymorphic objects of their most-derived class even if these objects are pointed by a reference/pointer to the base class. This without needing virtual functions.
To be able to do that, boost::serialization requires to know about existent polymorphic types: Archive::register_type must be called on the Archive object used to serialize.
This example shows how to register types and how to serialize them.
I'm wondering how this is achieved.
I tried to look at boost::serialization source code but failed: I'm not that good with template metaprogramming.
boost.serialization can write out your polymorphic class by using either typeid() or some user defined function get_key that returns the actual type of the polymorphic object.
register_type works by using the type supplied to instantiate a template that allows the archive to map the type identifier (either typeid(T) or the result of T::get_key()) to an object that knows how to serialize T.
boost::serialization uses the RTTI features of C++ to dynamically determine the type of an object.
You can look "typeid" function to determine dinamically the type of a class, even having only the base class pointer.
http://en.wikibooks.org/wiki/C++_Programming/RTTI
I'm using MFC's CArhive class to save off a project file for my app. One of the class names is wildly inaccurate and I'd like to change it, but simply changing the name everywhere renders previous archive files useless with an archive error. Is there a way to change the name of the archived class without rendering all previously saved files useless?
That is of course without using a typedef to access the existing class with a new name or keeping around a version of the class with the old name to read archived files and copying the read in objects to the same class with a new name.
The crucial point is that when you use DECLARE_SERIAL and IMPLEMENT_SERIAL, a CRuntimeClass member is added to your class containing the name in its m_lpszClassName field.
This CRuntimeClass object is also added to a list maintained by the framework that is searched when classes are dynamically created.
You need to make sure that the CRuntimeClass object contains the old name of your class in m_lpszClassName.
The two options you have are:
Override the construction of the
CRuntimeClass object to set the name
Change the class name stored in its
m_lpszClassName field after it has
been created
Overriding the construction of the CRuntimeClass object
To do this, you will need to make your own versions of DECLARE_DYMAMIC, DECLARE_DYNCREATE, DECLARE_SERIAL, IMPLEMENT_DYMAMIC, IMPLEMENT_DYNCREATE, and IMPLEMENT_SERIAL.
You can just copy and rename the existing implementations.
In your version of IMPLEMENT_DYNAMIC, you need to change the code that constructs the CRuntimeClass so that it is initialised with the old class's name.
Changing the class name stored in the m_lpszClassName field after the CRuntimeClass object has been created
As the CRuntimeClass is created by a static initializer, I don't think that you can do this from within your class.
I think that the best place to do it is in your application's InitInstance.
Add a static char* variable to your application's class containing the old class name.
Then, in InitInstance, set the m_lpszClassName field in your class's CRuntimeClass.
The first method has the advantage of
keeping changes within the class
itself.
The second makes the application
aware of the class in a way that it
possibly shouldn't be.
Either way, the first thing to do is to completely familiarise yourself with the way dynamic creation and serialization work.
There is a 3rd option which I took. I originally named one of my serializable classes CEvent which didn't seem to be a problem on VC6.0; but on VS2010 there is a MFC built-in class called CEvent so I had to change it.
So, I fixed it by modifying old format files before calling COleServerDoc::OnOpenDocument
I simply, open, read to memory, find and replace CEvent with any other 6 character (has to be same size) class name, write and save as new filename, then open and read new file, no problem.
I'm changing file extension for the new version anyway, so it all works out.
What is a Class and Object in C++?
Can we say that a Class is an Object?
A Class is like a blueprint, an object is like a house built from that blueprint.
You can have many houses with the same layout/floorplan (read class), but each is it's own instance (read object). Each has it's own owner, furniture, etc.
Note that there are also objects whose blueprint is not a class (e.g. integers).
An object is an instance of a class.
An object is some data, which has an address in run-time memory.
There are different types of object (e.g. int, float, etc.). You can create user-defined types, called 'classes'.
For example, I can define Dog as a class ...
class Dog {};
... and then create several objects, each of which is one instance of that class ...
Dog fido;
Dog spot;
I will try to give more technical explanation rather than an abstract one. I think that definitions like "a class is a blueprint and an object is something made from this blueprint" are impossible to understand for newbies simply because these kind of definitions are abstract and context-less.
Classes and objects have a pure abstract meaning in the object oriented world but for simplicity I will reduce the definition to a more practical one.
Consider the following statement:
int a;
"int" is a type and is "a" is a variable which has the type "int".
C++ provides various ways to let the programmer define new types; for example:
typedef int* int_ptr;
int_ptr a;
In this example , a new type is defined int_ptr.
"int_ptr" is a type , "a" is a variable which has the type "int_ptr".
Another example:
struct Point
{
int x;
int y;
};
Point a;
Here, a new type is defined, "Point", and "a" is a variable which has the type "Point".
So what is a class in C++? A class is another way to define a new type, just like the other ways mentioned above.
What is an object? An object is a variable which has a type that was defined using the class keyword.
For example:
class SmartPoint
{
public:
Point(x,y);
Move(x,y);
protected:
int x,y ;
};
SmartPoint a;
In this example, a new type is defined, "SmartPoint", and "a" is a variable which has the type "SmartPoint".
You may ask then what is different between a type defined by using the "class" keyword or "struct" keyword or "typedef" — but that is a matter for another discussion.
No, an object is an instance of a class.
No, an object is an instance of a class...
Unless...
If you are implementing a software design tool that allows you to represent classes, interfaces, properties, inheritance, associations, aggregations, etc., then at runtime, yes, each class you place in the designer will be an object instance of the Class class. Ok, couldn't help myself finding an example so twisted and meta.
Now seriously, a class is not an object.
Class is a collection of data member and member function.
Class is a user define data type.
Object is a class type variable.
Objects are also called instance of the class.
Each object contains all members(variables and functions) declared in the class. We can access any data member or member function from object of that class using . operator.
Here is an anology.
we have a classification called vehicles. Each vehicle will have some properties like :
seating capacity
fuel capacity
fuel consumption
type of transmission
Car, bike, truck, are some instances of vehicles. Each may have different set of properties.
Here vehicles is a class and all the properties are it's members and car, bike, truck are objects of the class vehicles.
No,class is not a object.
A class is a data type and object is the variable(instance) of class data type.
C++ supports many paradigms, but not the 'everything is an object' style of object-oriented programming. Classes exist in the source code, but do not exist at run time. Even runtime type information doesn't preserve Classes as object, but only provides a capability to get opaque ids which correspond to the type.
Class: A class defines a particular type's behaviours and properties.
Object: An object is an instance of a class.
For example, if you have a Dog named Bingo.
Dog would be the class defining its behaviours and properties
Bingo would be an object that is an instance of the Dog class
Strictly speaking, a Class is not an Object in C++.
But in languages such as C# and Java that supports reflection, classes can be used like objects but that is a more advance topic and probaly not what the original question is asking.
A class is not an object.
In simpler C language, a class is like a struct type, but more complex.
Using a C struct example as analogy:
struct class_ {
int attribute00;
float attribute02;
...
}
struct class_ object_ = {0, 0.0, ...};
struct class_ is act like a class and object_ is act like an object.
struct class_ has no physical storage in memory, object_ has physical storage in memory.
In human language, a word 'house' (as class) can defined in dictionary as place to stay, with doors, with windows, and rooms that you can only speak with your mouth to tell other people what is a house. A physical house (as object) is a solid build house on a land that you can move in and stay with your family.
A word 'house' take no physical occupation of land or space.
A physical house occupy land and space.
Class is collection of data and functions,its user defined data type.Class is specification for object.So you can say that object is variable for class or object is instance of class.
A class is a logical construct while object is its physical copy.
A class can be thought of as a mould from which multiple objects are created which appear identical to the class
Objects can be thought of as carbon copies of the class.
A perfect example of inheritance principle.
A class can be thought of as a parent of its children - objects
Object is an data or a function which has an adress in run time memory and are also called as instances of class .
Thus object is an class type variable or entity of c++ programming language.
In object-oriented programming , a class is a template definition of the method s and variable s in a particular kind of object . ... Subclasses can also define their own methods and variables that are not part of their superclass. The structure of a class and its subclasses is called the class hierarchy.
This is analogous to asking if a cat is a "My Kitten Mittens".
In C++, Objects are essentially the variables and Classes are the types of their values.
Short Answer: In Languages C++, Java: No.
In Languages like Python: Yes
When you define a class, you define a blueprint for a data type. This doesn't actually define any data, but it does define what the class name means, that is, what an object of the class will consist of and what operations can be performed on such an object.
A class definition starts with the keyword class followed by the class name; and the class body, enclosed by a pair of curly braces. A class definition must be followed either by a semicolon or a list of declarations. For example, we defined the Box data type using the keyword class as follows:
class Box
{
public:
double length; // Length of a box
double breadth; // Breadth of a box
double height; // Height of a box
};
The keyword public determines the access attributes of the members of the class that follow it. A public member can be accessed from outside the class anywhere within the scope of the class object. You can also specify the members of a class as private or protected which we will discuss in a sub-section.
A class is a user-defined blueprint or prototype from which objects are created. It represents the set of properties or methods that are common to all objects of one type.
Example:
class Person {
//..properties
//..methods
}
An Object is an instance of a Class or created from a class.
Example:
Person John = new Person(); //Creating an object of Person class
John.property1 = value; //setting value of property1 for John which is of Person
//Type
Both classes and instances are objects, but object oriented programming doesn't force the language to have classes & instances.