polymorphism problems from java to c++

Hi,

I am looking at the Artemis framework for component-based entity frameworks which is in Java.

A quick bit of background: Component-based entity frameworks are used for developing games by trying to avoid deep hierarchies. This stuff is all pretty new to me but I know both java and c++.

Here is a piece of Java code from the Artemis framework I am struggling to port into c++:

public <T extends Manager> T getManager(Class<T> managerType) {
return managerType.cast(managers.get(managerType));
}

Is this something that c++ can also do? A nice one-liner that casts our object back into the correct sub-class type using templates?

The obvious problem is that we don't have the Class keyword in c++ so I'm struggling with understanding how one would write a "get Manager of class X" function.

In short, is there a way to avoid having to call something similar to this function:

Manager *getManager( string type)
{
return pointer to the base class
}

And later relying on dynamic_cast to get back to a concrete Sub-type, say SpecialManager *manager = dynamic_cast<SpecialManager*>(getManager("special"));




> so I'm struggling with understanding how one would write a "get Manager of class X" function.

C++ is statically typed; in general, we prefer doing things with types at compile time.

Here is a toy (but complete) example of a customizable meta-function to get the manager for a type:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <iostream>
#include <type_traits>

struct manager_for_arrays // manager for arrays
{
    template < typename T, std::size_t N > void manage( T (&array)[N] )
    { std::cout << "manager_for_arrays::manage()\n" ; }
};

template < typename T, typename ENABLER = void > // meta-function to get manager type
struct get_manager { using manager_type = typename T::manager_type ; } ;

template < typename T > // partial specialization for arrays
struct get_manager< T, typename std::enable_if< std::is_array<T>::value, void >::type >
{ using manager_type = manager_for_arrays ; } ;

template < typename T > void foo( T& object ) // function using the manager
{ typename get_manager<T>::manager_type().manage(object) ; }

struct a_manager
{
    template < typename T > void manage( T& object )
    { std::cout << "a_manager::manage()\n" ; }
};

struct another_manager
{
    template < typename T > void manage( T& object )
    { std::cout << "another_manager::manage()\n" ; }
};

struct A { using manager_type = a_manager ; };
struct B { using manager_type = another_manager ; };

struct C {} ;

struct a_third_manager
{
    template < typename T > void manage( T& object )
    { std::cout << "a_third_manager::manage()\n" ; }
};

template <> struct get_manager<C> // complete specialization for C
{ using manager_type = a_third_manager ; } ;

int main()
{
    A a ; foo(a) ; // a_manager::manage()
    B b ; foo(b) ; // another_manager::manage()
    C c ; foo(c) ; // a_third_manager::manage()
    double d[20] ; foo(d) ; // manager_for_arrays::manage()
}
I am a bit worried that I would get myself tangled in this template code for my project because it would require me to implement much of my code using templates.
Since I'm working on a relatively simple project, I am just going to expose my individual managers that are heavily used with pointers that are explicitly set to the correct type outside my managers list.
The data container can still be iterated through normally, but if a part of my program requires a specific manager, I will use a specific function to retreive his pointer directly.
Thanks for the great post. Looks like I need to take a really long look how to use templates to fully understand your code!
OMG!
OMG?
Topic archived. No new replies allowed.