-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy path51_Virtual_Functions.cpp
More file actions
88 lines (69 loc) · 3.2 KB
/
51_Virtual_Functions.cpp
File metadata and controls
88 lines (69 loc) · 3.2 KB
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
#include <iostream>
using namespace std;
/*
A virtual function is a member function in the base class that is expected to redefine in derived classes.
In the last example, the info() method in the derived class shadows the info() method in the base class. However, if a pointer of Base type is created to point to an object of
Derived class and call the info() method, it calls the info() method of the Base class. In other words, the member function of Base is not overridden. To avoid this, the info()
method of the Base class should be declared as virtual using "virtual" keyword in base class and "override" specifier in derived class.
If the virtual method is redefined in the derived class, the method of derived class is executed even if it is called by a pointer of the base class object pointing to a derived
class object. In such a case, the method is said to be overridden. So, virtual methods are also an integral part of polymorphism in C++.
*/
class Base {
public:
virtual void info(){ //Declaring info() method as virtual
cout << "Base class!" << endl;
}
};
class Derived : public Base {
public:
void info() override{ //Overriding virtual method info() in derived class
//void inf() override{ //causing an error.
cout << "Derived class!" << endl;
}
};
/*
Using the "override" specifier prompts the compiler to display error messages when some mistakes are made:
- Methods with incorrect names. For example: if virtual method in base class is named info(), but the overridden method accidentally named as inf().
- Methods with different return types. For example: if virtual method is of type void, but the overridden method of derived class is of int type.
- Methods with different parameters. For example: if the parameters of the virtual method and the overridden methods don't match.
- No virtual function is declared in the base class.
*/
//Virtual destructor
class A {
public:
A() = default;
virtual void print(){
cout << "Base Class A" << endl;
}
virtual ~A() = default;
//~A() = default;
};
class B: public A{
private:
int* pr;
public:
B(int x = 1) : pr(new int{x}){}
void print() override{
cout << *pr * *pr << endl;
}
~B(){
delete pr;
cout << "pr is deleted." << endl;
}
};
int main(){
Derived d;
Base* ptr = &d;
ptr->info();
cout << endl;
B* a = new B(2); //pointer to B class pointing to B object
a->print();
delete a; //invokes B class destructor, which deletes the dynamic memory acquired by the B object
A* b = new B(3); //pointer to A class pointing to B object
b->print();
delete b; //invokes B class destructor
/*
If we declare the A class destructor as virtual, the B class destructor is called when we delete a pointer to A class pointing to a B object. But if we don't declare the destructor
as virtual, when we delete b which is a A* pointing to B object, the destructor of the A class is called, which does not deallocate the dynamic memory acquired by the B object
*/
}