This is for a "game engine" as a bit of programming practice. All of my GameObjects are component based, where each component adds a functionality to its parent GameObject and all of these components descend from a base Component class which has virtual methods making it polymorphic.
When I read in these gameobject definitions from an XML file some components need to know about others for example a physics component needs to be aware of the transform component for the physics calculations. However if these components aren't present in the XML file then occasionally it throws up nasty null-pointers and endless rabbit hole call stack chasing to find the XML typo I fudged while half asleep.
My solution was to have a node in the XML file as an assertion that a component of this type should exist and possibly throw an exception or another appropriate action if it doesnt.
Eg.
<ComponentRequirement type="ComponentTransform">myTransformComponent</ComponentRequirement>
So I need a way of representing this in C++. The first idea, template classes to change according to what type of component it's the proxy of since this class needs to act like their unproxied component. I've solved that with some operator overloading so long as the class is a template class.
template <class T>
class ComponentRequirement {
public:
T* operator->() { (I chose the arrow operator because the CompReq class will never be referenced as a pointer)
return this->component;
}
//Other unrelated functions . . .
private:
T* component;
};
And this is all fine and dandy at compile time because I can just say
ComponentRequirement<ComponentTransform> req = ComponentRequirement("myComponentTransform");
But I need to be able to specify what that template type in place of the will be from a string when I read the XML in. I thought a hashmap could do it but I dont think the type name even "is" anything other than a human readable compiler hint so I couldn't use it as a hashmap value.
Can this be done and how could I go about implementing it? Inserting some string literal into a "black-box of magic" and get something that can be used as a template argument. And if it helps, everything that will be the value of "T" is polymorphic.
Or is there a better solution to my problem. It needs to be able to act as any Component I put into it and it needs to be discernable at runtime.
EDIT 1:
In my components I have a read and write function. If I read the component requirement in there I can make sure the template has the right value because each component is seperate.
I can then evaluate the requirements with a virtual function and a few functions in the gameobject class to check it's a valid configuration. This could solve the problem.
At a first glance I would use the factory pattern for your problem. That way you can create classes to create your objects given a different string without specifying the exact class you need at compile time unlike with normal typed constructors. The analogy I see people use are Virtual Constructors.
http://www.oodesign.com/factory-pattern.html
In essence you would have a map of factories (creator objects).
Define some top level interface for your components, such as IComponent.
Define a factory class for every component you want to generate that has a Create Instance method. I recommend the Create Instance method should be part of an interface like IFactory.
During setup of your program create your map and assign factories to particular keys. ActorCreator["MyComponent"] = new MyComponentFactory();
When you want to create an object read from an XML node you can just call the create instance method on the returned factory for the key. auto myComponent = ActorCreator[readXML]->CreateInstance();
You now have an actor/components whose concrete type has been decided at runtime instead of compile time.
Coming from Delphi, I'm used to using class references (metaclasses) like this:
type
TClass = class of TForm;
var
x: TClass;
f: TForm;
begin
x := TForm;
f := x.Create();
f.ShowModal();
f.Free;
end;
Actually, every class X derived from TObject have a method called ClassType that returns a TClass that can be used to create instances of X.
Is there anything like that in C++?
Metaclasses do not exist in C++. Part of why is because metaclasses require virtual constructors and most-derived-to-base creation order, which are two things C++ does not have, but Delphi does.
However, in C++Builder specifically, there is limited support for Delphi metaclasses. The C++ compiler has a __classid() and __typeinfo() extension for retrieving a Delphi-compatible TMetaClass* pointer for any class derived from TObject. That pointer can be passed as-is to Delphi code (you can use Delphi .pas files in a C++Builder project).
The TApplication::CreateForm() method is implemented in Delphi and has a TMetaClass* parameter in C++ (despite its name, it can actually instantiate any class that derives from TComponent, if you do not mind the TApplication object being assigned as the Owner), for example:
TForm *f;
Application->CreateForm(__classid(TForm), &f);
f->ShowModal();
delete f;
Or you can write your own custom Delphi code if you need more control over the constructor call:
unit CreateAFormUnit;
interface
uses
Classes, Forms;
function CreateAForm(AClass: TFormClass; AOwner: TComponent): TForm;
implementation
function CreateAForm(AClass: TFormClass; AOwner: TComponent): TForm;
begin
Result := AClass.Create(AOwner);
end;
end.
#include "CreateAFormUnit.hpp"
TForm *f = CreateAForm(__classid(TForm), SomeOwner);
f->ShowModal();
delete f;
Apparently modern Delphi supports metaclasses in much the same way as original Smalltalk.
There is nothing like that in C++.
One main problem with emulating that feature in C++, having run-time dynamic assignment of values that represent type, and being able to create instances from such values, is that in C++ it's necessary to statically know the constructors of a type in order to instantiate.
Probably you can achieve much of the same high-level goal by using C++ static polymorphism, which includes function overloading and the template mechanism, instead of extreme runtime polymorphism with metaclasses.
However, one way to emulate the effect with C++, is to use cloneable exemplar-objects, and/or almost the same idea, polymorphic object factory objects. The former is quite unusual, the latter can be encountered now and then (mostly the difference is where the parameterization occurs: with the examplar-object it's that object's state, while with the object factory it's arguments to the creation function). Personally I would stay away from that, because C++ is designed for static typing, and this idea is about cajoling C++ into emulating a language with very different characteristics and programming style etc.
Type information does not exist at runtime with C++. (Except when enabling RTTI but it is still different than what you need)
A common idiom is to create a virtual clone() method that obviously clones the object which is usually in some prototypical state. It is similar to a constructor, but the concrete type is resolved at runtime.
class Object
{
public:
virtual Object* clone() const = 0;
};
If you don't mind spending some time examining foreign sources, you can take a look at how a project does it: https://github.com/rheit/zdoom/blob/master/src/dobjtype.h (note: this is a quite big and evolving source port of Doom, so be advised even just reading will take quite some time). Look at PClass and related types. I don't know what is done here exactly, but from my limited knowledge they construct a structure with necessary metatable for each class and use some preprocessor magic in form of defines for readability (or something else). Their approach allows seamlessly create usual C++ classes, but adds support for PClass::FindClass("SomeClass") to get the class reference and use that as needed, for example to create an instance of the class. It also can check inheritance, create new classes on the fly and replace classes by others, i. e. you can replace CDoesntWorksUnderWinXP by CWorksEverywhere (as an example, they use it differently of course). I had a quick research back then, their approach isn't exceptional, it was explained on some sites but since I had only so much interest I don't remember details.
Developing a modular application, I want to inject some helper classes into each module. This should happen automated. Note that my helpers have state, so I can't just make them static and include them where needed.
I could store all helpers in a map with a string key and make it available to the abstract base class all modules inherit from.
std::unordered_map<std::string, void*> helpers;
RendererModule renderer = new RendererModule(helpers); // argument is passed to
// base class constructor
Then inside a module, I could access helpers like this.
std::string file = (FileHelper*)helpers["file"]->Read("C:/file.txt");
But instead, I would like to access the helpers like this.
std::string file = File->Read("C:/file.txt");
To do so, at the moment I separately define members for all helpers in the module base class, and set them for each specific module.
FileHelper file = new FileHelper(); // some helper instances are passed to
// multiple modules, while others are
// newly created for each one
RendererModule renderer = new RendererModule();
renderer->File = file;
Is there a way to automate this, so that I don't have to change to module code when adding a new helper to the application, while remaining with the second syntax? I an not that familiar with C macros, so I don't know if they are capable of that.
I think I see what your dilemma is, but I have no good solution for it. However, since there are no other answers, I will contribute my two cents.
I use the combination of a few strategies to help me with these kinds of problems:
If the helper instance is truly module-specific, I let the module itself create and manage it inside.
If I don't want the module to know about the creation or destruction of the helper(s), or if the lifetime of the helper instance is not tied to the module that is using it, or if I want to share a helper instance among several modules, I create it outside and pass the reference to the entry-point constructor of the module. Passing it to the constructor has the advantage of making the dependency explicit.
If the number of the helpers are high (say more than 2-3) I create an encompassing struct (or simple class) that just contains all the pointers and pass that struct into the constructor of the module or subsystem. For example:
struct Platform { // I sometimes call it "Environment", etc.
FileHelper * file;
LogHelper * log;
MemoryHelper * mem;
StatsHelper * stats;
};
Note: this is not a particularly nice or safe solution, but it's no worse than managing disparate pointers and it is straightforward.
All the above assumes that helpers have no dependency on modules (i.e. they are on a lower abstraction of dependency level and know nothing about modules.) If some helpers are closer to modules, that is, if you start to want to inject module-on-module dependencies into each other, the above strategies really break down.
In these cases (which obviously happen a lot) I have found that a centralized ModuleManager singleton (probably a global object) is the best. You explicitly register your modules into it, along with explicit order of initialization, and it constructs all the modules. The modules can ask this ModuleManager for a reference to other modules by name (kind of like a map of strings to module pointers,) but they do this once and store the pointers internally in any way they want for convenient and fast access.
However, to prevent messy lifetime and order-of-destruction issues, any time a module is constructed or destructed, the ModuleManager notifies all other modules via callbacks, so they have the chance to update their internal pointers to avoid dangling pointers and other problems.
That's it. By the way, you might want to investigate articles and implementations related to the "service locator" pattern.
Say I have two classes with different names but the exactly same structure. It there a way to cast an object of the one class to one of the other?
This might sound stupid to do but there is a reason why I want to do that. The architecture of my application provides the abstract classes component and storage The ready application will contain several specialized components derived from component and each of them will define its own storage type, derived from storage. During initialization of the application, for each component there will be a storage object of its custom storage type created and passed as pointer to the component.
This way all component stay completely independent which is great for re-usability and testing. But, of course, there is a need to exchange informations between components. To do that with independence in mind, I want to let two components get a storage pointer pointing to the same storage. The pointer by constraint must be of the component specific storage type.
framework code (abstract classes)
class Storage {};
class Component {
public:
void SetStorage(Storage* storage);
private:
Storage* storage;
};
example component
class PhysicsStorage : public Storage;
class PhysicsComponent : public Component;
another component
class CollisionStorage : public Storage; // same structure as PhysicsStorage as both components need the same data like world coordinates and rotations of all forms in the 3d space
class CollisionComponent : public Component;
main application
#include "system.h"
PhysicsStorage Worlddata;
PhysicsComponent Physics;
CollisionComponent Collision;
Physics.SetStorage(&Worlddata);
Collision.SetStorage(&Worlddata); // this points to a PhysicsStorage but that is actually the same like a CollisionStorage which is expected
So I wonder if there is a way of casting the pointer of say PhysicsStorage* to CollisionStorage*. In this case, both are defined in the file of their related component class. And both are derived from abstract Storage.
I only want to do that in the case that both custom storage types have exactly the same structure. Otherwise it would be senseless. I am not so familiar with advances pointer usage so I wonder if there is a way to do that. What I know is that you can cast to a base class, but this isn't what I want here. Using a shared storage type for two components would break independence. Thanks a lot!
This may work, and it may not. I believe this is a case of undefined behavior, and I would avoid doing this in production code.
Consider instead pushing the common fields and methods up into a new class and having ComponentOneStorage and ComponentTwoStorage inherit that class. Then you can pass around pointers/references to the base class instead, which will give you access to the common data without having to cast between incompatible pointer types.
I was reading "Design Patterns: Elements of Reusable Object-Oriented Software", (specifically the chapter about the prototype design pattern) and it stated that...
"Prototype is particularly useful with static languages like C++ where classes are not objects, and little or no type information is available at run-time." (pg 121)
(emphasis mine)
I had always thought that classes were synonymous to objects, and I'm confused as to what this statement means. How are classes not objects, and why does it matter if a language is static?
A class in C++ is not an object: a class is a description of how to build an object, and a reference to a type of an object.
Compare with a language like Python: in python, like in C++, you instantiate an object from a class. Unlike C++, the class you used is also an object: it usually has type type, and you can create new ones at runtime, manipulate them like any other object, or even create objects which are classes which themselves have different types.
You may be wondering why you'd want this, and usually you don't need it -- it's like C++ template meta-programming, you only need it when you need it because you can't achieve your goal in any other way. It's probably also the case that problems you'd solve in Python with meta-classes you'd solve in C++ using template meta-programming.
In C++, this declares a class:
class A {
public:
int a;
};
whereas this declares an object:
A a;
One cannot interrogate a class a run-time, as one can interrogate an object. It makes sense to say, "object 'a', what is your address? Please invoke operator+. etc." In C++, with its static typing, it makes no sense to say, "Class A, what is your list of members? Please add a new member, "b"."
In other languages (Python comes to mind), one can manipulate classes in this way, because each class is also an object. In addition to serving as a template for objects, the class itself is an object -- it can be printed, modified, etc.
For example, a class could describe what a book is: Name, Author, Date of Publishing, Description.
An object of the "Book" class would be a specific book: C++ Primer Plus, Stephen Prata, 2005, A book that teaches C++.
So, classes are not the same as objects.
To expand on what Andrew Aylett said.
A class in C++ is not an object: a class is a description of how to build an object, and a reference to a type of an object.
Furthermore, in languages like Python or smalltalk. Everything is an object. A function is a object, a class is a object. As such these languages are Dynamically Typed, meaning that types are checked during runtime and variables can take on any type.
C++ is statically typed. Variables can only take on one type, and type checking is performed at compile time.
So in python for instance, you can modify a class on the fly. Add functions and fields, because it is an object, and can be modified.
What that sentence refers is to is the fact that classes are not first-order entities in a language like C++. In other languages, you can pass a class as a parameter to a function, e.g., the same way as you can pass an object or a function as a parameter.
There are many more implications of being classes first-order entities or not, e.g., the possibility of modifying a class at runtime, or inspecting the full internals of a class, etc.
Usually classes are found to be first-order entities in dynamic languages like ruby, or in the meta object protocol for lisp, etc.
Hope this clarifies it a bit.
Classes are not the same as Objects. A class is (more or less) the type, and an Object is the instance, simmiliar to the following:
int i;
YourClass object;
Here you wouldn't say i and int are the same -- neither are YourClass and object.
What the statement wants to say: Many object orientated languages are very object orientated, so that they start making everything (or nearly everything) an object (of one or another class). So in many languages a class would be an instance (hence an object) of some class class (which can be confusing).
This sometimes has advantages, as you can treat classes (that's types) in such languages like you could treat any other object. You can than do very dynamic stuff with them, like store them in variables or even manipulate the classes during runtime (e.g. to create new classes your program finds the need to have).
Take a look at this c++-similiar pseudo code:
YourClass myObject = new YourClass(); // creates an object (an instance)
Class baseClass = myObject.get_class(); // store the class of myObject in baseClass. That's storing a type in a variable (more or less)
Class subClass = myObject.inherit(); // dynamically create a new class, that only exists in variable subClass (a Class-object), inheriting from baseClass
subClass.add_method(some_function); // extend the new class by adding a new method
subClass.get_class() subClass.create_instance(); // declare a new variable (object) of your newly created type
BaseClass another_onne = subClass.create_instance(); // also valid, since you inherited
This obviously doesn't translate well to c++, because of c++'s strict typing. Other languages are more dynamic in typing, and there this flexibility can come in handy (and make thinks more complicated; sometimes both at the same time). Still I think it explains the principle, if you understand c++.
I had always thought that classes were synonymous to objects
The language in OOP literature is sometimes not specific. It doesn't help either that programming languages have somewhat different notions of what an object is.
A class is a template or definition from where objects (instances of that class) are created. That is, a class provides the structure, type signatures and behaviors that objects of that class (or type... more on that later.)
An object is just a location in memory of an instance of that class.
Wikipedia provides good documentation on this. I suggest you read it:
http://en.wikipedia.org/wiki/Class_(computer_programming)
http://en.wikipedia.org/wiki/Object_(object-oriented_programming)
Also, there is the concept of a type. A type (or interface as sometimes called in some literature or programming languages) is typically the collection of type/method signatures (and possibly behavior). Things like Java interfaces and C++ pure virtual classes tend to represent types (but aren't exactly the same).
Then a class that conforms to that type (be it interface or pure virtual class) is an implementation of that type.
That class, that type implementation is just a recipe of how to construct objects of that class/type in memory.
When you instantiate a class/type, you reify, construct an instance (object) of that class in memory.
In C++, a class is not an object since a class itself is not instantiated. A C++ class is not an instance of some other class (see the definitions I put above.)
OTH, in languages like Java, a class itself is represented by instances of a primordial class (java.lang.Class). So a class X has an object in memory (an java.lang.Class instance) associated with it. And with it, with that "class" object, you can (in theory) instantiate or manufacture another instance (or object) of class/type X.
It can get confusing. I strongly suggest you search and read the literature on classes, types, prototypes and objects/instances.
and I'm confused as to what this statement means. How are classes not
objects,
As explained above. A class is not an object. An object is an instance, a piece of memory constructed and initialized by the "recipe" of a class or type.
and why does it matter if a language is static?
That part of the book is a bit misleading because Java, for example, is statically typed and yet, classes can be object themselves. Perhaps the text is refering to dynamically typed languages (like JavaScript) where classes can also be objects or instances.
My suggestion is to never use the word object, and to simply limit the vocabulary to "classes" and "instances". But that's my personal predilection. Other people might disagree, and so be it.
The simpler I can put it for you to understand it:
An object is a "physical" instance of a class. It consumes memory while the program is running.
A class describes an object: Hierarchy, properties, methods. A class it's like a "template" for creating objects.
When a class is said to be an object, it means that there's an object that represents that class at runtime. In C++, classes are dissolved at compile time. Their instances (i.e. objects) are merely sequences of bytes holding the object's fields, without any reference to the class itself. Now, C++ does provide some type information at runtime via RTTI, but that's only for polymorphic types, and is not considered a class object.
The lack of having objects that represent classes at runtime is the reason there's no reflection in C++ - there's just no way to get information about a certain class, as there's no object that represent it.
BTW, C++ is considered a 2-level language: objects are instances of classes, but classes are not instances of anything, because they only exist at compile type. On 3-level languages such as C# and Java, classes are also objects at runtime, and as such, are themselves instances of yet another class (Class in Java, Type in C#). The last class is an instance of itself, hence the language only has 3 levels. There are languages with more levels, but that's beyond the scope of this question...