Practice 20.
Inheritance and Polymorphism
Video: cpp-mat-gyak20-inheritance.mp4
This is the object-oriented version of the practice-10 when we implemented rooms and house.
person.h:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#ifndef PERSON_H
#define PERSON_H
class Person
{
public:
Person(int e = 10, int c = 7, int h = 2, int m = 5);
void setEnergy(int e) { energy += e; }
void setCleanliness(int c) { cleanliness += c; }
void setHunger(int h) { hunger += h; }
void setMood(int m) { mood += m; }
void printStats();
private:
int energy;
int cleanliness;
int hunger;
int mood;
};
#endif
person.cpp:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include "person.h"
Person::Person(int e, int c, int h, int m)
: energy(e), cleanliness(c), hunger(h), mood(m)
{
}
void Person::printStats()
{
std::cout << "Energy level: " << energy << '\n';
std::cout << "Cleanliness level: " << cleanliness << '\n';
std::cout << "Hunger level: " << hunger << '\n';
std::cout << "Mood level: " << mood << '\n';
std::cout << '\n';
}
room.h:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#ifndef ROOM_H
#define ROOM_H
#include <string>
#include "person.h"
class Room
{
public:
Room(float w, float l);
virtual ~Room(){}
float roomArea() const;
virtual void cleanRoom(Person& p, float time);
virtual std::string roomToString() const { return "Room"; };
// pure virtual methods
virtual Room* clone() const = 0;
virtual void activity(Person& p, float time) = 0;
private:
float width;
float length;
float height = 2.5;
};
#endif // ROOM_H
room.cpp:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include "room.h"
Room::Room(float w, float l)
: width(w), length(l)
{
}
void Room::cleanRoom(Person& p, float time)
{
std::cout << "Cleaning..." << '\n';
p.setEnergy((int)(time * (-3.8))); // time * 1
p.setCleanliness((int)(time * (-0.7)));
p.setHunger((int)(time * 0.6));
p.setMood((int)(time * (-3.5)));
}
float Room::roomArea() const
{
return width * length;
}
derivedrooms.h:
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
#ifndef DERIVED_ROOMS_H
#define DERIVED_ROOMS_H
#include "room.h"
class Bedroom : public Room
{
public:
Bedroom(float w, float l) : Room(w, l) {}
Bedroom(const Bedroom& b) : Room(b) {}
Bedroom* clone() const override {
return new Bedroom(*this); }
void activity(Person& p, float time) override;
std::string roomToString() const override {
return "Bedroom"; }
};
class Bathroom : public Room
{
public:
Bathroom(float w, float l) : Room(w, l) {}
Bathroom(const Bathroom& b) : Room(b) {}
Bathroom* clone() const override {
return new Bathroom(*this); }
void activity(Person& p, float time) override;
std::string roomToString() const override {
return "Bathroom"; }
};
class Kitchen : public Room
{
public:
Kitchen(float w, float l) : Room(w, l) {}
Kitchen(const Kitchen& k) : Room(k) {}
Kitchen* clone() const override {
return new Kitchen(*this); }
void activity(Person& p, float time) override;
std::string roomToString() const override {
return "Kitchen"; }
};
class LivingRoom : public Room
{
public:
LivingRoom(float w, float l) : Room(w, l) {}
LivingRoom(const LivingRoom& l) : Room(l) {}
LivingRoom* clone() const {
return new LivingRoom(*this); }
void activity(Person& p, float time) override;
std::string roomToString() const override {
return "Living room"; }
};
#endif
derivedrooms.cpp:
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
#include <iostream>
#include "derivedrooms.h"
void Bedroom::activity(Person& p, float time)
{
std::cout << "Sleeping..." << '\n';
p.setEnergy((int)time); // time * 1
p.setCleanliness((int)(time * (-0.3)));
p.setHunger((int)(time * 0.5));
p.setMood((int)(time * 0.8));
}
void Bathroom::activity(Person& p, float time)
{
std::cout << "Taking a shower..." << '\n';
p.setEnergy((int)time * (-0.2));
p.setCleanliness((int)(time * 1.3)); // time * 1
p.setHunger((int)(time * 0.5));
p.setMood((int)(time * 0.8));
}
void Kitchen::activity(Person& p, float time)
{
std::cout << "Eating..." << '\n';
p.setEnergy((int)time);
p.setCleanliness((int)(time * (-0.6)));
p.setHunger((int)time); // time * 1
p.setMood((int)(time * 0.8));
}
void LivingRoom::activity(Person& p, float time)
{
std::cout << "Watching Netflix..." << '\n';
p.setEnergy((int)time * (-0.3));
p.setCleanliness((int)(time * (-0.3)));
p.setHunger((int)(time * 0.5));
p.setMood((int)(time * 1.2));
}
house.h:
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
#ifndef HOUSE_H
#define HOUSE_H
#include "room.h"
#include "derivedrooms.h"
#include <vector>
class House
{
public:
House();
House(const std::vector<Room*>& rooms);
House(const House& h);
House& operator=(const House& h);
~House();
int roomNumber() { return rooms.size(); }
Room* getRoom(size_t index);
float houseArea();
void addRoom(Room* r);
void printRooms();
private:
std::vector<Room*> rooms;
void copy(const House& rhs);
void release();
};
#endif // HOUSE_H
house.cpp:
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
#include <iostream>
#include "house.h"
House::House()
{
addRoom(new Bedroom(3, 3));
addRoom(new Bathroom(2, 2));
addRoom(new Kitchen(1.5, 3));
}
House::House(const std::vector<Room*>& rooms)
{
for (Room* room : rooms)
{
this->rooms.push_back(room->clone());
}
}
House::House(const House& h)
{
copy(h);
}
House& House::operator=(const House& h)
{
if (this != &h)
{
release();
copy(h);
}
return *this;
}
House::~House()
{
release();
}
void House::copy(const House& h)
{
for (auto room : h.rooms)
{
rooms.push_back(room->clone());
}
}
void House::release()
{
for (auto r : rooms)
{
delete r;
}
}
Room* House::getRoom(size_t index)
{
if (index < rooms.size())
{
return rooms.at(index);
}
return nullptr;
}
float House::houseArea()
{
float area = 0.0; // don't forget to initialize
for (auto& room : rooms)
{
area += room->roomArea();
}
return area;
}
void House::addRoom(Room* r)
{
rooms.push_back(r);
}
void House::printRooms()
{
for (Room* room : rooms)
{
std::cout << "Room type: " << room->roomToString()
<< ", area: " << room->roomArea() << '\n';
}
}
main.cpp:
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
/* pointer (new, delete, nullptr), destruktor, öröklódés,
* statikus és dinamikus típus, absztrakt osztály,
* virtuális és tisztán virtuális metódus, overriding,
* kovariancia és kontravariancia, többszörös öröklődés(?) */
#include <iostream>
#include "house.h"
#include "derivedrooms.h"
int main()
{
House mansion;
std::cout<<"Mansion area: "<< mansion.houseArea()<<'\n';
mansion.addRoom(new LivingRoom(7.6, 6.7));
mansion.addRoom(new Bedroom(3.8, 4.7));
std::cout<<"Mansion area: "<< mansion.houseArea()<< '\n';
std::cout<<"Rooms in the mansion: " << '\n';
mansion.printRooms();
std::cout << '\n';
Person guy;
guy.printStats();
mansion.getRoom(2)->activity(guy, 3);
// should have null-check
guy.printStats();
mansion.getRoom(0)->activity(guy, 4);
guy.printStats();
mansion.getRoom(1)->cleanRoom(guy, 0.5);
guy.printStats();
mansion.getRoom(3)->activity(guy, 7);
guy.printStats();
std::cout << '\n';
House building = mansion;
return 0;
}
The expected output:
$ g++ -Wall -Wextra *.cpp -o house
$ ./house
Mansion area: 17.5
Mansion area: 86.28
Rooms in the mansion:
Room type: Bedroom, area: 9
Room type: Bathroom, area: 4
Room type: Kitchen, area: 4.5
Room type: Living room, area: 50.92
Room type: Bedroom, area: 17.86
Energy level: 10
Cleanliness level: 7
Hunger level: 2
Mood level: 5
Eating...
Energy level: 13
Cleanliness level: 6
Hunger level: 5
Mood level: 7
Sleeping...
Energy level: 17
Cleanliness level: 5
Hunger level: 7
Mood level: 10
Cleaning...
Energy level: 16
Cleanliness level: 5
Hunger level: 7
Mood level: 9
Watching Netflix...
Energy level: 14
Cleanliness level: 3
Hunger level: 10
Mood level: 17
Financed from the financial support ELTE won from the Higher Education
Restructuring Fund of the Hungarian Government.