typeid and type_info Win32

B

boris111

Been experimenting with the typeid and type_info in c++ WIN32. My
goal is to create a simple Java-like class loader.

1) The first version of GetFirstInstance does not behave as expected.
It looks like I'm doing it right. Why does it typeid(*setting).name()
give me the base class? The second version of GetFirstInstance does
work, but I don't understand why it works, but the first does not.

2) Is there a cleaner way to do what I'm doing here? To me the
template <typename T> used in GetFirstInstance doesn't look very
intuitive to use as a user of the provided classes. The ideal
situation would be for the user of the to specify something like
DerivedClass *derived = cloud->GetFirstInstanceOf(DerivedClass);

int main (int argc, char ** argv)
{

DerivedClass settings;
TpsSettingsCloud *cloud = new TpsSettingsCloud();
cloud->InsertSettings(&settings);
DerivedClass *foundClass = dynamic_cast said:
GetFirstInstanceOf(&typeid(DerivedClass)));

if(foundClass == &settings)
{
printf("Class found correctly");
}
else
printf("GetFirstInstanceOf NOT successful");
}

#include <typeinfo>

class TpsSettingsCloud
{

public:

TpsSettingsCloud(){}

void InsertSettings(BaseClass *settings)
{
m_settings.push_back(settings);
}

//METHOD THAT COMPILES, but DOES NOT WORK as expected
BaseClass *GetFirstInstanceOf (type_info *type)
{

BaseClass *setting;
for (int i = 0; i < m_settings.size(); i++)
{
setting = m_settings;
string vectorName = typeid(*setting).name(); //SOME REASON this
equals the class name of the derived class, but the next version of
this method DOES work on the same exact line of code.
string typeInfoName = type->name();
if( typeid(*setting).name() == type->name())
return setting;
}

return NULL;
}


//METHOD THAT WORKS
template <typename T>
BaseClass *GetFirstInstanceOf (T *type)
{

BaseClass *setting;
for (int i = 0; i < m_settings.size(); i++)
{
setting = m_settings;

string vectorName = typeid(*setting).name();
string typeInfoName = type->name();
if( typeid(*setting).name() == type->name())
return setting;
}

return NULL;
}



private:
vector <BaseClass *> m_settings;

};



class BaseClass
{
};

class DerivedClass : public BaseClass
{
};
 
M

Michael DOUBEZ

boris111 said:
Been experimenting with the typeid and type_info in c++ WIN32. My
goal is to create a simple Java-like class loader.


You could look into Boost.Extension and see how he did it:
http://boost-extension.redshoelace.com/docs/boost/extension/index.html

I don't say it is the best way but you could get some ideas.
1) The first version of GetFirstInstance does not behave as expected.
It looks like I'm doing it right.

No. The standard doesn't guaranty that thr type_info returned by typeid
be the same object. But they will have the same value.
Since name() returns a const char*, the returned pointer may not be the
same between multiple call of typeid.


Why does it typeid(*setting).name()
give me the base class? The second version of GetFirstInstance does
work, but I don't understand why it works, but the first does not.

The type_info is likely to be different between different compilation
unit (CU); this is why your templated version works and the other not.
Note that it works here because you have only one CU that instantiate
the template. If the same template get instantiated in different CU, you
will likely have the same problem.

The solution is to compare the values, not the pointers.
2) Is there a cleaner way to do what I'm doing here? To me the
template <typename T> used in GetFirstInstance doesn't look very
intuitive to use as a user of the provided classes. The ideal
situation would be for the user of the to specify something like
DerivedClass *derived = cloud->GetFirstInstanceOf(DerivedClass);

The following seem fine to me:
DerivedClass *derived = cloud->GetFirstInstanceOf<DerivedClass>();

[snip]
//METHOD THAT COMPILES, but DOES NOT WORK as expected
BaseClass *GetFirstInstanceOf (type_info *type)
{

BaseClass *setting;
for (int i = 0; i < m_settings.size(); i++)
{
setting = m_settings;
string vectorName = typeid(*setting).name(); //SOME REASON this
equals the class name of the derived class, but the next version of
this method DOES work on the same exact line of code.
string typeInfoName = type->name();
if( typeid(*setting).name() == type->name())
return setting;
}

return NULL;
}


//METHOD THAT WORKS
template <typename T>
BaseClass *GetFirstInstanceOf (T *type)
{

BaseClass *setting;
for (int i = 0; i < m_settings.size(); i++)
{
setting = m_settings;

string vectorName = typeid(*setting).name();
string typeInfoName = type->name();
if( typeid(*setting).name() == type->name())
return setting;
}

return NULL;
}

[snip]
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,768
Messages
2,569,575
Members
45,053
Latest member
billing-software

Latest Threads

Top