How do I retain the type_info here?

When I run this:

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
#include <iostream>
#include <typeinfo>
#include <set>
using namespace std;

class Person {public:  string name; virtual ~Person() { } };
class Girl : public Person {public: Girl (string girlName) {name = girlName;} };
class Guy : public Person {public: Guy (string guyName) {name = guyName;} };

set<Person*> everybody;

int main() {
	Girl *girl = new Girl ("Martha");
	Guy *guy = new Guy ("John");
	cout << girl->name << endl;
	cout << typeid(girl).name() << endl << endl;
	cout << guy->name << endl; 
	cout << typeid(guy).name() << endl << endl;
	
	everybody.insert (girl);  // type_info is lost!
	everybody.insert (guy);   // type_info is lost!
	
	for (set<Person*>::iterator it = everybody.begin(); it != everybody.end(); ++it)
	{
		cout << (*it)->name << endl;
		cout << typeid(*it).name() << endl;
	}
	return 0;
}


I get the output:

Martha
Girl

John
Guy

Martha
Person
John
Person

Of course, I want to retain the Girl and Guy statuses of the two, but theses are lost after placing them in the everybody set. Yet, I need the everybody set in my program. How do I retain their type_info when I extract them back from set everybody?
Last edited on
Furthermore, this change did not help:
1
2
3
4
5
6
7
8
9
10
11
12
13
class Person {public:  string name; string gender; virtual ~Person() { } };
class Girl : public Person {public: Girl (string girlName) {name = girlName; gender = "Female";} };
class Guy : public Person {public: Guy (string guyName) {name = guyName; gender = "Male";} };

// and then in main():
	for (set<Person*>::iterator it = everybody.begin(); it != everybody.end(); ++it)
	{
		if ((*it)->gender == "Female")
			static_cast<Girl*> (*it);
		else
			static_cast<Guy*> (*it);
		cout << typeid(*it).name() << endl;
	}


They both still remain of type Person*.
Last edited on
Reference docs say that "RTTI" is required. Is that a flag for compiler?

Are you sure that you need the type? No other way?
I have virtual functions that I want to run on the members of "everybody", including updating their files (each person has their own txt file for saving and loading, and guys and girls store different information) so I need their type back. "everybody" usually has over 1000 people, so I have to contain them, and later on I will have many derived classes of Person, so I think "everybody" is the right choice. Furthermore "everybody" expands when a member of "everybody" meets someone, say Guy m from "everybody" meets Girl f: everyone whom f knows will automatically be inserted in "everybody" in my program (and everyone they know in turn also joins "everybody" and so forth...), so I don't see any other choice but for "everybody" to be a set<Person*>.
Last edited on
pointers are not classes. If you want to see the types of the pointed-to objects, then use typeid(**it)
Ah! So I never lost their types after all. Thanks Cubbi. And the article Josue mentioned I'm sure I will need very soon.
Let Person have public save() and private virtual foo() = 0. Implement foo() in Boy and Girl. Call foo() in save(). Now Boys and girls will save differently even though you call save via a Person*.

That is the very purpose of virtual functions.
Topic archived. No new replies allowed.