Thread: Problem with RTTI and a factory method

  1. #1
    Registered User
    Join Date
    Apr 2004
    Posts
    72

    Problem with RTTI and a factory method

    So I'm learning RTTI. I have a factory method that returns random objects. Each time I check the count of each animal (derived from Mammal), it doesn't add up the dogs, cats etc. All it does is return Mammal. Why am I not getting the derived object names instead? Thanks.

    Code:
    #include <iostream> 
    #include <fstream>
    #include <string>
    #include <typeinfo>  
    
    class Mammal 
    {
    public: 
    };
    
    class Cat : public Mammal
    {
    public:
    };
    
    class Platypus : public Mammal 
    {
    public: 
    };
    
    class Dog : public Mammal
    {
    public:
    };
    
    Mammal *factory() 
    {
    	switch (rand()%3) 
    	{
    	case 0: return new Dog;
    	case 1: return new Cat;
    	case 2: return new Platypus;
    	}
    
    	return 0;
    }
    
    int main()
    {
    	Mammal *ptr; 
    	int i;
    	int c = 0, d = 0, p = 0;
    
    	for (i = 0; i < 10; i++) 
    	{
    		ptr = factory();
    
    		std::cout << "Object is " << typeid(*ptr).name() << std::endl;
    		std::cout << std::endl;
    
    		if (typeid(*ptr) == typeid(Dog)) 
    			d++;
    		if (typeid(*ptr) == typeid(Cat)) 
    			c++;
    		if (typeid(*ptr) == typeid(Platypus)) 
    			p++;
    	}
    
    	std::cout << "Cats: " << c << std::endl;
    	std::cout << "Dogs: " << d << std::endl;
    	std::cout << "Platypus: " << p << std::endl;
    
    	system("pause");
    	return 0;
    }

  2. #2
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Class Mammal has no virtual functions, so no RTTI information is generated for it. A good compiler with all warnings enabled should perhaps have warned you about that.

    The easiest thing to do is to give Mammal a virtual destructor. That's a very good idea anyway, because if it doesn't have one, then the line you're missing in the loop (delete ptr, or else you're leaking) would generate undefined behaviour.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  3. #3
    Registered User
    Join Date
    Apr 2004
    Posts
    72
    Makes sense. I added a virtual destructor to class Mammal. As I compiled, I got the following warning:

    warning C4541: 'typeid' used on polymorphic type 'Mammal' with /GR-; unpredictable behavior may result

    I'm still debating what that really is.

  4. #4
    carry on JaWiB's Avatar
    Join Date
    Feb 2003
    Location
    Seattle, WA
    Posts
    1,972
    "Think not but that I know these things; or think
    I know them not: not therefore am I short
    Of knowing what I ought."
    -John Milton, Paradise Regained (1671)

    "Work hard and it might happen."
    -XSquared

  5. #5
    Registered User
    Join Date
    Apr 2004
    Posts
    72
    Yeah, I just googled that. I had to go to Project - Properties - C++ - Language - Enable Run-Time Type Info. I thought it was on by default. Thanks for the help. It's working as expected now.

Popular pages Recent additions subscribe to a feed