List of objects of different classes C++ - c++

I already figured out to use polymorphism and have the list store the pointer to the baseClass, but after successfully placing it there, I would like to know what class the object was originally. I am using templates for the classes, and wanted to have an another field which would be an enum of basic types.
Now the question: is there a way to check (during runtime or during compilation) an
(if T == int)
field = INT
I though maybe something with the preprocessor but I'm not familiar with that.

The whole idea behind polymorphism is to hide the specific implementation making it transparent in your program flow. Using type of class as an indicator will make your code bloat with if statements and will be harder to maintain.
I suggest you reconsider your design and make an abstract class with the intended behavior methods and use this class type as the list objects type. Than for each object call the interface method (which was declared in the abstract class and implemented in the deriving classes)

You can use operator typeid.
For example, if T is a pointer to a base class:
if (typeid(SomeDerivedClass) == typeid(*T))
...
(It is somewhat unclear for me why you speak about int in connection with polymorphism. int cannot be derived from.)

What you are probably looking for is known as type traits. They allow you to determine and act on the attributes of a specific type. You could start with std::is_integral() and std::is_floating_point() and build from there depending on your requirements.
enum Type
{
Unknown,
Integral,
Float
};
....
Type field = Unknown;
if(std::is_integral<T>::value)
{
field = Integral;
}
else if(std::is_floating_point<T>::value)
{
field = Float;
}

The C++ preprocessor knows nothing about C++. It is a generic symbol manipulator which can be used with most any programming language, or for that matter, any text processing application, such as a feature of word or equation layout processing.
You might look into the typeid operator as one way to build such a mechanism, though heed the Misuses of RTTI section further down on that page.

Related

C++ Class References

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.

Vector of pointers to base type, find all instances of a given derived type stored in a base type

Suppose you have a base class inside of a library:
class A {};
and derived classes
class B: public A {};
class C: public A {};
Now Instances of B and C are stored in a std::vector of boost::shared_ptr<A>:
std::vector<boost::shared_ptr<A> > A_vec;
A_vec.push_back(boost::shared_ptr<B>(new B()));
A_vec.push_back(boost::shared_ptr<C>(new C()));
Adding instances of B and C is done by a user, and there is no way to determine in advance the order, in which they will be added.
However, inside of the library, there may be a need to perform specific actions on B and C, so the pointer to the base class needs to be casted to B and C.
I can of course do "trial and error" conversions, i.e. try to cast to Band C(and any other derivative of the base class), until I find a conversion that doesn't throw. However, this method seems very crude and error-prone, and I'm looking for a more elegant (and better performing) way.
I am looking for a solution that will also work with C++98, but may involve boost functionality.
Any ideas ?
EDIT:
O.k., thanks for all the answers so far!
I'd like to give some more details regarding the use-case. All of this happens in the context of parametric optimization.
Users define the optimization problem by:
Specifying the parameters, i.e. their types (e.g. "constrained double", "constrained integer", "unconstrained double", "boolean", etc.) and initial values
Specifying the evaluation function, which assigns one or more evaluations (double values) to a given parameter set
Different optimization algorithms then act on the problem definitions, including their parameters.
There is a number of predefined parameter objects for common cases, but users may also create their own parameter objects, by deriving from one of my base classes. So from a library perspective, apart from the fact that the parameter objects need to comply with a given (base-class) API, I cannot assume much about parameter objects.
The problem definition is a user-defined C++-class, derived from a base-class with a std::vector interface. The user adds his (predefined or home-grown) parameter objects and overloads a fitness-function.
Access to the parameter objects may happen
from within the optimization algorithms (usually o.k., even for home-grown parameter objects, as derived parameter objects need to provide access functions for their values).
from within the user-supplied fitness function (usually o.k., as the user knows where to find which parameter object in the collection and its value can be accessed easily)
This works fine.
There may however be special cases where
a user wants to access specifics of his home-grown parameter types
a third party has supplied the parameter structure (this is an Open Source library, others may add code for specific optimization problems)
the parameter structure (i.e. which parameters are where in the vector) may be modified as part of the optimization problem --> example: training of the architecture of a neural network
Under these circumstances it would be great to have an easy method to access all parameter objects of a given derived type inside of the collection of base types.
I already have a templated "conversion_iterator". It iterates over the vector of base objects and skips those that do not comply with the desired target type. However, this is based on "trial and error" conversion (i.e. I check whether the converted smart pointer is NULL), which I find very unelegant and error-prone.
I'd love to have a better solution.
NB: The optimization library is targetted at use-cases, where the evaluation step for a given parameter set may last arbitrarily long (usually seconds, possibly hours or longer). So speed of access to parameter types is not much of an issue. But stability and maintainability is ...
There’s no better general solution than trying to cast and seeing whether it succeeds. You can alternatively derive the dynamic typeid and compare it to all types in turn, but that is effectively the same amount of work.
More fundamentally, your need to do this hints at a design problem: the whole purpose of a base class is to be able to treat children as if they were parents. There are certain situations where this is necessary though, in which case you’d use a visitor to dispatch them.
If possible, add virtual methods to class A to do the "specific actions on B and C".
If that's not possible or not reasonable, use the pointer form of dynamic_cast, so there are no exceptions involved.
for (boost::shared_ptr<A> a : A_vec)
{
if (B* b = dynamic_cast<B*>(a.get()))
{
b->do_something();
}
else if (C* c = dynamic_cast<C*>(a.get()))
{
something_else(*c);
}
}
Adding instances of B and C is done by a user, and there is no way to determine in advance the order, in which they will be added.
Okay, so just put them in two different containers?
std::vector<boost::shared_ptr<A> > A_vec;
std::vector<boost::shared_ptr<B> > B_vec;
std::vector<boost::shared_ptr<C> > C_vec;
void add(B * p)
{
B_vec.push_back(boost::shared_ptr<B>(p));
A_vec.push_back(b.back());
}
void add(C * p)
{
C_vec.push_back(boost::shared_ptr<C>(p));
A_vec.push_back(c.back());
}
Then you can iterate over the Bs or Cs to your hearts content.
I would suggest to implement a method in the base class (e.g. TypeOf()), which will return the type of the particular object. Make sure you define that method as virtual and abstract so that you will be enforced to implement in the derived types. As for the type itself, you can define an enum for each type (e.g. class).
enum class ClassType { ClassA, ClassB, ClassC };
This answer might interest you: Generating an interface without virtual functions?
This shows you both approaches
variant w/visitor in a single collection
separate collections,
as have been suggested by others (Fred and Konrad, notably). The latter is more efficient for iteration, the former could well be more pure and maintainable. It could even be more efficient too, depending on the usage patterns.

Alternate ways to identify polymorphic objects?

I've been searching all through the web and I seem to not find any alternate way of doing comparing if two polymorphic objects are the same type, or if a polymorphic object IS a type. The reason for this is because I am going to implement a Entity System inside of my game that I am currently creating.
I have not found another way of doing this other than with the use macros or a cast (the cast not being a portable method of doing so). Currently this is how I am identifying objects, is there a more efficient or effective way of doing this? (without the use of C++ RTTI)
I pasted it on pastebin, since pasting it here is just too much of a hassle.
http://pastebin.com/2uwrb4y2
And just incase you still do not understand exactly what I'm trying to achieve, I'll try to explain it. An entity in a game is like an object inside of the game (e.g. a player or enemy), it have have components attached to it, these components are data for an entity. A system in the entity system is what brings the data and logic of the game together.
For example, if I wanted to display a model up on the screen it would be similar to this:
World world; // Where all entities are contained
// create an entity from the world, and add
// some geometry that is loaded from a file
Entity* e = world.createEntity();
e->add(new GeometryComponent());
e->get<GeometryComponent>()->loadModel("my_model.obj"); // this is what I want to be able to do
world.addSystem(new RenderingSystem());
// game loop
bool isRunning = true;
while(isRunning)
{
pollInput();
// etc...
// update the world
world.update();
}
EDIT:
Here's a framework, programmed in Java, that does mainly what I want to be able to do.
http://gamadu.com/artemis/tutorial.html
See std::is_polymorphic. I believe boost has it too.
If T is a polymorphic class (that is, a class that declares or inherits at least one virtual function), provides the member constant value equal true. For any other type, value is false.
http://en.cppreference.com/w/cpp/types/is_polymorphic
Edit:
Why can't you just do this in your example?
Entity* e = world.createEntity();
GemoetryComponent* gc = new GeometryComponent();
gc->loadModel("my_model.obj");
e->add(gc);
Create the structure before stripping the type information.
If you're determined not to use C++'s built-in RTTI, you can reimplement it yourself by deriving all classes from a base class that contains a virtual method:
class Base {
public:
virtual string getType() = 0;
};
Then every derived class needs to overload this method with a version that returns a distinct string:
class Foo : public Base {
public:
string getType() { return "Foo"; }
};
You can then simply compare the results of calling getType() on each object to determined if they are the same type. You could use an enumeration instead of a string if you know up front all the derived classes that will ever be created.
Entity* e = world.createEntity();
e->add(new GeometryComponent());
e->get<GeometryComponent>()->loadModel("my_model.obj");
// this is what I want to be able to do
First the simple: there is a base type to all of the components that can be added, or else you would not be able to do e->add(new GeometryComponent()). I assume that this particular base has at least one virtual function, in which case the trivial solution is to implement get as:
template <typename T>
T* get() {
return dynamic_cast<T*>(m_component); // or whatever your member is
}
The question says that you don't want to use RTTI, but you fail to provide a reason. The common misundertandings are that RTTI is slow, if that is the case, consider profiling to see if that is your case. In most cases the slowness of dynamic_cast<> is not important, as dynamic_casts should happen rarely on your program. If dynamic_cast<> is a bottleneck, you should refactor so that you don't use it which would be the best solution.
A faster approach, (again, if you have a performance bottleneck here you should redesign, this will make it faster, but the design will still be broken) if you only want to allow to obtain the complete type of the object would be to use a combination of typeid to tests the type for equality and static_cast to perform the downcast:
template <typename T>
T* get() {
if (typeid(*m_component)==typeid(T))
return static_cast<T*>(m_component);
else
return 0;
}
Which is a poor man's version of dynamic_cast. It will be faster but it will only let you cast to the complete type (i.e. the actual type of the object pointed, not any of it's intermediate bases).
If you are willing to sacrifice all correctness (or there is no RTTI: i.e. no virtual functions) you can do the static_cast directly, but if the object is not of that type you will cause undefined behavior.

Can a "type" be passed in C++?

[A follow up to this question: Possible to instantiate object given its type in C++?
In Java, you can have a method parameter of type Class, and callers can pass in Foo.class. I don't consider this aspect reflection, though what you can do with the passed-in Class obviously is. Does C++ have any mechanism for passing in a "type"? Since I know there is little/nothing I could do with that passed-in type, I suspect the answer is "no".
Obviously, templates provide this facility, but they're not what I'm looking for.
Sounds like RTTI (run-time type identification) is what you're looking for. From http://en.wikibooks.org/wiki/C++_Programming/RTTI :
The typeid operator, used to determine
the class of an object at runtime. It
returns a reference to a
std::type_info object, which exists
until the end of the program, that
describes the "object".
How about RTTI and typeid?
No. This feature is part of "reflection" and is only possible in languages like Java which actually put information about classes in the compiled binary.
C++ (typically) does not actually store any information about classes at all in the resulting binary. (Excepting a few bits necessary for std::type_info to work)
In reality, there's nothing like the "Type" provided by Java and friends available in C++, and therefore you cannot pass it to a method.
If you want to pass a type to a method for the purpose of instantiating it, you can actually do this in a better way (this works with Java and friends too)
#include <memory>
struct IMyType
{
virtual ~IMyType();
virtual MyMethod();
};
struct IElementFactory
{
virtual std::auto_ptr<IMyType> GetNewItem() const = 0;
virtual ~IElementFactory();
};
void MyMethodThatAcceptsAType(const IElementFactory& factory)
{
std::auto_ptr<IMyType> instance(factory.GetNewItem());
//Use your instance like normal.
}
This is better even in Java land because this code maintains type safety, while the reflection based code does not.

How do Concepts differ from Interfaces?

How do Concepts (ie those recently dropped from the C++0x standard) differ from Interfaces in languages such as Java?
Concepts are for compile-time polymorphism, That means parametric generic code. Interfaces are for run-time polymorphism.
You have to implement an interface as you implement a Concept. The difference is that you don't have to explicitly say that you are implementing a Concept. If the required interface is matched then no problems. In the case of interfaces, even if you implemented all the required functions, you have to excitability say that you are implementing it!
I will try to clarify my answer :)
Imagine that you are designing a container that accepts any type that has the size member function. We formalize the Concept and call it HasSize, of course we should define it elsewhere but this is an example no more.
template <class HasSize>
class Container
{
HasSize[10]; // just an example don't take it seriously :)
// elements MUST have size member function!
};
Then, Imagine we are creating an instance of our Container and we call it myShapes, Shape is a base class and it defines the size member function. Square and Circle are just children of it. If Shape didn't define size then an error should be produced.
Container<Shape> myShapes;
if(/* some condition*/)
myShapes.add(Square());
else
myShapes.add(Circle());
I hope you see that Shape can be checked against HasSize at compile time, there is no reason to do the checking at run-time. Unlike the elements of myShapes, we could define a function that manipulates them :
void doSomething(Shape* shape)
{
if(/* shape is a Circle*/)
// cast then do something with the circle.
else if( /* shape is a Square */)
// cast then do something with the square.
}
In this function, you can't know what will be passed till run-time a Circle or a Square!
They are two tools for a similar job, though Interface-or whatever you call them- can do almost the same job of Concepts at run-time but you lose all benefits of compile-time checking and optimization!
Concepts are likes types (classes) for templates: it's for the generic programming side of the language only.
In that way, it's not meant to replace the interface classes (assuming you mean abstract classes or other C++ equivalent implementation of C# or Java Interfaces) as it's only meant to check types used in template parameters to match specific requirements.
The type check is only done at compile time like all the template code generation and whereas interface classes have an impact on runtime execution.
Concepts are implicit interfaces. In C# or Java a class must explicitly implement an interface, whereas in C++ a class is part of a concept merely as long as it meets the concept's constraints.
The reason you will see concepts in C++ and not in Java or C# is because C++ doesn't really have "interfaces". Instead, you can simulate an interface by using multiple inheritance and abstract, memberless base classes. These are somewhat of a hack and can be a headache to work with (e.g. virtual inheritance and The Diamond Problem). Interfaces play a critical role in OOP and polymorphism, and that role has not been adequately fulfilled in C++ so far. Concepts are the answer to this problem.
It's more or less a difference in the point of view. While an interface (as in C#) is specified similar to a base class, a concept can also be matched automatically (similar to duck-typing in Python). It is still unclear to which level C++ is going to support automatic concept matching, which is one of the reasons why they dropped it.
To keep it simple, as per my understanding.
Concept is a constraint on the template parameter of a Type (i.e., class or struct) or a Method
Interfaces is a contract that Type (i.e., class Or struct) has to implement.