Virtual Methods in C++

Hello,

I have the following input:
3
lion 100 35
tiger 100 23
tiger 120 40

and I expected output to be:
lion 3500
tiger 123
tiger 160

But the output is:
lion 1
tiger 1
tiger 1

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
92
93
94
95
96
97
98
#include<iostream>
#include<string>
using namespace std;

class animal
{
protected:
	int weight, power;
public:
	int type;
	int getType()
	{
		return type;
	}
	void setType(int t)
	{
		type = t;
	}
	animal() {}
	animal(int w, int p)
	{
		weight = w;
		power = p;
	}
	virtual int animalpower()
	{
		return 1;
	}
};

class lion : public animal
{
public:
	lion(int w, int p) :animal(w, p)
	{

	}
	int animalpower()
	{
		return weight * power;
	}
};
class tiger :public animal
{
public:

	tiger(int w, int p) :animal(w, p)
	{

	}
	int animalpower()
	{
		return weight + power;
	}
};

int main()
{
	int n; cin >> n;
	string which;
	int w, p;

	animal* arr = new animal[n];

	for (int i = 0; i < n; i++)
	{
		cin >> which;
		cin >> w >> p;
		if (which[0] == 'l')
		{
			//lion *l = new lion(w, p);
			//l->setType(1);
			lion l(w, p);
			l.setType(1);
			arr[i] = l;
		}
		else
		{
			tiger t(w, p);
			t.setType(2);
			arr[i] = t;
		}
	}
	for (int i = 0; i < n; i++)
	{
		if (arr[i].getType() == 1)
		{
			cout <<"lion "<< arr[i].animalpower()<<endl;
		}
		else
		{
			cout << "tiger " << arr[i].animalpower()<<endl;
		}

	}

	return 0;
}
If you do this:
1
2
3
animal a;
lion l(0, 0);
a = l;
you may be changing the values of a's members, but a is still an animal and not a lion.

Polymorphism can only be used through pointers and references. For example,
 
std::unique_ptr<animal> a(new lion(0, 0));
Now a is a pointer to an animal, but the object being pointed to is a lion.

In other words, arr should be an array of pointers to animals, not merely an array of animals. The code you commented out was actually correct. You need to dynamically allocate a lion or tiger and then assign it to one of the pointers in arr.
You can simplify a fair bit and probably a bit further than this but here is a start:
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
#include<iostream>
#include<string>

using namespace std;

class Animal
{
protected:
    string type;
    int weight, power;
public:
    string getType() {  return type; }
    virtual int getPower() { return power * weight; }
};

class lion : public Animal
{
public:
    lion(int w, int p) { type = "LION"; weight = w; power = p;}
};

class tiger :public Animal
{
public:
    tiger(int w, int p) { type = "TIGER"; weight = w; power = p; }
};

int main()
{
    int n;
    cin >> n;
    Animal* arr = new Animal[n];

    string which;
    int w, p;

    for (int i = 0; i < n; i++)
    {
        cin >> which;
        cin >> w >> p;
        if (which[0] == 'l')
        {
            lion l(w, p);
            arr[i] = l;
        }
        else
        {
            tiger t(w, p);
            arr[i] = t;
        }
    }

    for (int i = 0; i < n; i++)
        cout << arr[i].getType() << ' ' << arr[i].getPower() << '\n';

    delete[] arr;

    return 0;
}



3
lion 100 35
tiger 100 23
tiger 120 40
LION 3500
TIGER 2300
TIGER 4800
Program ended with exit code: 0
Last edited on
Using polymorphism and dynamic memory, possibly:

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
#include <iostream>
#include <string>

class Animal {
protected:
	int weight {}, power {};

public:
	Animal() {}
	Animal(int w, int p) : weight(w), power(p) {}
	virtual std::string getType() const = 0;
	virtual int getPower() const {return power * weight; }
};

class Lion : public Animal {
public:
	Lion(int w, int p) : Animal(w, p) {}
	std::string getType() const { return "Lion"; }
};

class Tiger : public Animal
{
public:
	Tiger(int w, int p) : Animal(w, p) {}
	std::string getType() const { return "Tiger"; }
};

int main()
{
	size_t n {};

	std::cout << "How many animals: ";
	std::cin >> n;

	auto arr {new Animal*[n]{}};

	std::string which;
	int w {}, p {};

	for (size_t i = 0; i < n; ++i) {
		std::cout << "Animal type (l or t): ";
		std::cin >> which;

		std::cout << "Weight power: ";
		std::cin >> w >> p;

		if (which[0] == 'l')
			arr[i] = new Lion(w, p);
		else
			arr[i] = new Tiger(w, p);
	}

	for (size_t i = 0; i < n; ++i)
		std::cout << arr[i]->getType() << " " << arr[i]->getPower() << '\n';

	for (size_t i = 0; i < n; ++i)
		delete arr[i];

	delete[] arr;
}



How many animals: 3
Animal type (l or t): l
Weight power: 12 23
Animal type (l or t): l
Weight power: 23 45
Animal type (l or t): t
Weight power: 2 3
Lion 276
Lion 1035
Tiger 6

Topic archived. No new replies allowed.