Search code examples
c++typeid

memory allocation using runtime type information


I got to know about run-time type information in c++. This can be accomplished with typeid keyword in c++.

int main()
{
        //these two where user-defined class
        Complex x;
        Point3D y;

        const type_info& s = typeid(x);

        cout<<typeid(y).name()<<endl; //works...(1)
        cout<<s.name()<<endl;         //works...(2)

        Complex * tp = new s[10];     //does not work...(3)
}

As marked in the code, I was successful in printing out types of the data objects as in (1) and (2).

Now I wish to allocate memory by using type_info/typeid. Could anyone do this? Is it even possible. I do not have any virtual functions.

Can such a feat be accomplished by any other way. I do not want to use virtual functions as it has a negative effect on code vectorization.


Solution

  • No, this is not possible. What you are looking for is a factory.

    Here is an example of such a factory. Suppose you have these types:

    class point_t
    {
    };
    
    class complex_t : public point_t
    {
    };
    
    class point3d_t : public point_t
    {
    };
    

    You can define the following factory:

    typedef point_t* (*makeptr)();
    
    class point_factory
    {
       static point_t* make_complex()
       {
          return new complex_t();
       }
    
       static point_t* make_point3d()
       {
          return new point3d_t();
       }
       static std::map<std::string, makeptr> _map;
    public:
       static void init()
       {
          _map.insert(make_pair(typeid(complex_t).name(), &point_factory::make_complex));
          _map.insert(make_pair(typeid(point3d_t).name(), &point_factory::make_point3d));
       }
       static point_t* make_point(const type_info& type)
       {
          std::map<std::string, makeptr>::iterator pos = _map.find(type.name());
          if(pos != _map.end())
             return (*(pos->second))();
          return NULL;
       }
    };
    
    std::map<std::string, makeptr> point_factory::_map;
    

    And use it like this:

    point_factory::init();
    point_t* p = point_factory::make_point(typeid(point3d_t));