My first OO design does not work (inheritance and overloading)

Hi

My first post. I am quite familiar with the C language subset so I do not post this in the newbie forum. I hope it is OK. This is the first time I try to use more advanced OO features and it does not work.

I try to simulate what happens when two animals of unknown type meets at a water hole. I want each kind of animal to know what happens to it when it meets another animal. (E.g. the zebra knows that it is eaten by the lion.) Ibatiba is an unknown animal that takes the default behavior of the Animal class.

The line pLion->meet(pIbatiba); does not even compile (I think it should!) and the animals at the water hole perform the default behavior and not what I intend.

In other words: I want to treat the animals in a uniform way in the WaterHole class and I want any subclass of Animal to be able to implement a method for a meeting with any othher subclass of Animal or use the default behavior.

Can anyone explain to me how I should do.


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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#include <iostream>

class Animal {
public:
	virtual void meet(Animal * p);
};

void Animal::meet(Animal * P)
{
	std::cout << "Unknown behavior!" << std::endl; // default-behavior
}

class Ibatiba:public Animal {
};

class Zebra;

class Lion:public Animal {
public:
	void meet(Zebra * p);
};

void Lion::meet(Zebra * p)
{
	std::cout << "I eat" << std::endl;
}

class Zebra:public Animal {
public:
	void meet(Lion * p);
};

void Zebra::meet(Lion * p)
{
	std::cout << "I am devored!" << std::endl;
}

// A water hole with room for two animals
class WaterHole {
public:
	WaterHole(Animal * p1, Animal * p2);
	void lets_meet(void);
private:
	Animal * pa1;
	Animal * pa2;
};

WaterHole::WaterHole(Animal * p1, Animal * p2)
{
	pa1 = p1;
	pa2 = p2;
}
	
void WaterHole::lets_meet(void)
{
	pa1->meet(pa2);
	pa2->meet(pa1);
}

int main()
{
	Ibatiba * pIbatiba = new Ibatiba;
	Lion * pLion = new Lion;
	Zebra * pZebra = new Zebra;

	std::cout << "A day in Africa:\n";

	pLion->meet(pZebra);
	pZebra->meet(pLion);

// This does not work?
// But Ibatiba inherits from Animal...
// cpptst.cpp(80): error C2664: 'Lion::meet' : cannot convert parameter 1 from 'Ibatiba *' to 'Zebra *'
//
//	pLion->meet(pIbatiba);

	std::cout << "At the water hole:\n";

	WaterHole * pWaterHole = new WaterHole(pLion, pZebra);
	pWaterHole->lets_meet();

	return 0;
}


This is what i expect:

A day in Africa:
I eat
I am devored!
Unknown behavior!
At the water hole:
I eat
I am devored!

This is what I get:

A day in Africa:
I eat
I am devored!
At the water hole:
Unknown behavior!
Unknown behavior!

C++ doesn't directly provide a mechanism for what you want to do. Check this out:

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#include <iostream>
using namespace std;

class Lion;
class Zebra;

class Animal
{
public:

    virtual ~Animal(){}
    virtual int type() {return 0;}

    void meet(Animal * a)
    {
        int type1=type();
        int type2=a->type();

        if (meet_ftable[type1][type2]==0)
            cout << "undefined behavior!..." << endl;
        else
            meet_ftable[type1][type2](this,a);
    }

private:

    typedef void (*meet_func)(Animal *,Animal*);

    static const meet_func meet_ftable[3][3];

    static void lion_lion(Animal*,Animal*)
    {
        cout << "a lion meets another lion." << endl;
    }

    static void zebra_zebra(Animal*,Animal*)
    {
        cout << "a zebra meets another zebra." << endl;
    }

    static void lion_zebra(Animal*,Animal*)
    {
        cout << "a lion meets a zebra. ";
        cout << "lucky lion!" << endl;
    }

    static void zebra_lion(Animal*,Animal*)
    {
        cout << "a zebra meets a lion. ";
        cout << "poor zebra..." << endl;
    }
};

const Animal::meet_func Animal::meet_ftable[3][3]=
{
    0,  0,  0,
    0,  Animal::lion_lion,  Animal::lion_zebra,
    0,  Animal::zebra_lion, Animal::zebra_zebra
};

class Lion: public Animal
{
    virtual int type() {return 1;}
};

class Zebra: public Animal
{
    virtual int type() {return 2;}
};

int main()
{
    Animal a;
    Lion lion;
    Zebra zebra;

    Animal * pa = &a;
    Animal * pa1 = &lion;
    Animal * pa2 = &zebra;

    lion.meet(pa1);
    pa2->meet(&zebra);
    pa1->meet(pa2);
    zebra.meet(&lion);
    a.meet(pa1);
    pa->meet(&zebra);

    cout << "\nhit enter to quit...";
    cin.get();
    return 0;
}
Last edited on
Thank you very much for you reply!

I will be away for some weeks and will not be able to ask further questions on your solution.

Thank you again
Topic archived. No new replies allowed.