Inheritance problems

I have a base class that i would like to get some values from a subclass.
Im going to name the classes of animals so it is easy to understand what i mean.
Say i have a base class Animals and a sub class insects which have 2 classes under it. And one more class under Animals which is class cats. All the classes

I want to access specific stuff from the sub classes from the private data through the base class Animals.

I want to be able to access it somthing like this:
obj->getSwimmingSpeed() and obj->getFlySpeed().
I have tried to access it with somthing like this: virtual int getSwimmingSpeed() const = 0; but i dont think its right.

i have made a virtual function to find out what kind of animal it is and after that i want to get the data out like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
string animal;
animal = obj->getAnimalType();

if(animal == "cat")
{
    obj->getSwimmingSpeed();
}

if(animal == "honeybee")
{
    obj->getAvgHoney();
}
... This is what im trying to do if you understand what i mean

Base class
1
2
3
4
5
6
7
8
9
10
class Animals
{
private:
     int name;
     int nrOfLegs;    
public:
     virtual int getSwimmingSpeed() const = 0;
     virtual int getFlySpeed() const = 0;
     virtual int getAvgHoney() const = 0;
     virtual int getSomeData() const = 0;


sub class under Animlas
1
2
3
4
5
6
class Insects : public Animals
{
private:
     int someData;   
public:
     virtual int getSomeData() const;


sub class to Insects
1
2
3
4
5
6
class Honeybee : public Insects
{
private:
     int avgHoney;   
public:
     virtual int avgHoney() const;


sub class to Insects
1
2
3
4
5
6
class Fly : public Insects
{
private:
     int flySpeed;   
public:
     virtual int getFlySpeed() const;


sub class to Animlas
1
2
3
4
5
6
class Cats : public Animals
{
private:
     int swimmingSpeed;   
public:
     virtual int getSwimmingSpeed() const;


Perhaps i should do it in another way.
Thank you in advance =)
I haven't personally done too much work with inheritance and stuff like that, but I'll just throw a suggestion out there.

The thing is, if you do this:
1
2
3
4
5
6
7
8
9
10
class Animals
{
private:
     int name;
     int nrOfLegs;    
public:
     virtual int getSwimmingSpeed() const = 0;
     virtual int getFlySpeed() const = 0;
     virtual int getAvgHoney() const = 0;
     virtual int getSomeData() const = 0;

then your classes that are derived from Animals (the ones that you want to be instantiate-able, anyways) all have to define getSwimmingSpeed(), getFlySpeed(), getAvgHoney(), and getSomeData(). Unless you have a cat that can potentially fly and/or make honey, I'm not sure that this is what you want.

You could consider a dynamic_cast or static_cast:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
string animal;
animal = obj->getAnimalType();

if(animal == "cat")
{
    // We know it's a cat, so this should work:
    Cats* c = dynamic_cast<Cats*>(obj);
    c->getSwimmingSpeed();
}

if(animal == "honeybee")
{
    // So it's a honeybee, huh?
    Honeybee* h = dynamic_cast<Honeybee*>(obj);
    h->getAvgHoney();
}

Alternatively, since dynamic_cast will return a null pointer if the conversion failed, you can forget the getAnimalType() function completely and just do this:
1
2
3
4
5
6
7
8
9
10
Cats* c = dynamic_cast<Cats*>(obj);
if(c)
{
    c->getSwimmingSpeed();
}
// Or combine the first two lines above into one:
if(Honeybee* h = dynamic_cast<Honeybee*>(obj))
{
    h->getAvgHoney();
}

That will do what you're asking to do (barring the fact that the expression c->getSwimmingSpeed(); does absolutely nothing), though I have no clue if it's considered good or bad practice at all. (Anyone else have ideas?)
Pure virtual function is any function that is virtual and is ending with =0;
virtual void Foo() = 0;//pure virtual function
Pure virtual function may have implementation, but can't be called by object - you can only call it like Class::Function(), and you are only allowed to do so in classes that are derived from this class.
(about pure virtual funct. implementation -> see http://stackoverflow.com/questions/2089083/pure-virtual-function-with-implementation )
Each pure virtual function must be implemented in derived class.

Any class that contains pure virtual function is an abstract class. You can't create instance of an abstract class. You can, however, create a pointer to abstract class:
Animals* ptr;
This is used for polymorphism.

You have your problem, because you don't understand abstract class and polymorphism well. It happens :)

Abstract class works as a "blueprint". When you are writing many complex classes, sometimes you may want to split them into few smaller classes - like you want to do with animals. This feels natural. However, you must remember one thing: abstract class should have such functions, that will allow you to do what you want.

Let's take a look at this small example:
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
#include <string>
#include <iostream>
class Animal
{
private:
    std::string name;
public:
    Animal(std::string _name) : name(_name) {}
    virtual int GetLives() = 0;
    inline std::string GetName() { return name; }
};

class Cat : public Animal
{
public:
    Cat() : Animal("Cat") {}
    int GetLives() { return 9; }
    void Meow() { std::cout <<"Meow!" << std::endl; }

};

int main(int argc, char* args[] )
{
    Cat pussy;
    std::cout << "I'm a pussy! I'm a " << pussy.GetName() <<" and I have " << pussy.GetLives() << " lives! " << std::endl;
    pussy.Meow();

    Animal* pusy = new Cat();
    std::cout << "I'm a pusy! I'm a " << pusy->GetName() <<" and I have " << pusy->GetLives() << " lives! " << std::endl;
    //pusy->Meow(); -> This won't work! Class Animal has no member named "Meow()"
    return 0;
}

As you can see, with polymorphism we can't use Meow() on Animal*. What should we do about it?
You can cast it:
 
dynamic_cast<Cat*>(pusy)->Meow();

However, casting isn't something great. What is another option?

You could make function like
1
2
3
4
5
6
7
class Animal
{
//code...
public:

   virtual void Speak() = 0;
};


And have every animal implement it on its own. Or, you could use base class where you don't need to use Animal*.


Cheers!
Last edited on
As said before, the pure virtual methods (ones ending in =0;) are used as an interface. They force a standard API for any classes that inherit from them.

The glaring issue I see is that you are assuming all animals can swim or fly. A bee can't really swim but since you made the method getSwimmingSpeed() pure virtual method, the Bee class must implement it. Now if we talk semantics, the Bee class could just have an empty implementation, that is just virtual int getSwimmingSpeed() { } but now when a client calls on this method it might expect something to happen.

Reserve the pure virtual methods that are vital to your hierarchy. The end goal to enforce a standard. Defining that standard is probably the hardest part.

With the knowledge above on polymorphism, you should be good to move forward.
Hi guys and thanks for the responses :) I will try the dynamic_cast and see if it works. The thing is that im not going to know what kind of animal it is because im going to copy the animal class and get out all the info stored in it. And i dont want to write functions like getFlySpeed() to all classes under animal. Just an easy way to get the privite values from a derived class from the base class.
But thanks guys i will try it an see if it works =)
The dynamic_cast help me solve the problem. Thanks again guys :)
Topic archived. No new replies allowed.