
Section 16: Polymorphism
Function Overriding
- Function overriding is you can redefined the parent function in the child class. You use the same function name of the parent class in child class.
- 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#include <iostream>
using namespace std;
class Base
{
public:
void display()
{
cout << "Display of Base" << endl;
}
};
class Derived : public Base
{
public:
void display()
{
cout << "Display of Derived" << endl;
}
};
int main()
{
Derived d;
d.display();
return 0;
}
====OUTPUT====
Display of Derived
Virtual Functions
- If you don’t use
virtual
in the base function. Pointer object will call the base class.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```
#include <iostream>
using namespace std;
class Base
{
public:
void fun()
{
cout << "fun of Base" << endl;
}
};
class Derived : public Base
{
public:
void fun()
{
cout << "fun of Derived" << endl;
}
};
int main()
{
Derived d;
Base *ptr = &d;
ptr->fun();
return 0;
}
====OUTPUT====
fun of Base - If you use
virtual
in the base function. Pointer object will call the derived class.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 <iostream>
using namespace std;
class Base
{
public:
virtual void fun()
{
cout << "fun of Base" << endl;
}
};
class Derived : public Base
{
public:
void fun()
{
cout << "fun of Derived" << endl;
}
};
int main()
{
Derived d;
Base *ptr = &d;
ptr->fun();
return 0;
}
====OUTPUT====
fun of Derived
Runtime Polymorphism
- We can defined functions in the base class equals to zero, and the sub-classes must implement those functions, this is called pure virtual functions.
- 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
33
34#include <iostream>
using namespace std;
class Car
{
public:
virtual void start() { cout << "Car Started" << endl; }
};
class Innova : public Car
{
public:
void start() { cout << "Innova Started" << endl; }
};
class Swift : public Car
{
public:
void start() { cout << "Swift Started" << endl; }
};
int main()
{
Car *p = new Innova();
p->start();
p = new Swift();
p->start();
return 0;
}
====OUTPUT====
Innova Started
Swift Started
Abstract Classes
- If a base class has all concrete functions, it means this class’s purpose is to achieve reusability. And if a base class has some concrete functions and some pure virtual functions, it means this class’s purpose is to achieve reusability and polymorphism.
- If a base class has all pure virtual functions, it means this class’s purpose is to achieve polymorphism. This is also called interface.
- When you use pure virtual functions in the base class, they are the abstract class.
- If you make a class as abstract class, you can’t initialize it. For example,
Car c;
is not allowed. - If the sub-class didn’t overwrite the virtual functions from the base class, the sbu-class will also become abstract class.
Section 17: Friend and Static Members / Inner Classes
Friend Function and Classes
- Friend function is a global function outside function which can access all the members of a class.
- When you declare the friend function, you need to add the class name before calling the class as friend.
- 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#include <iostream>
using namespace std;
class Your;
class My
{
private: int a;
protected: int b;
public: int c;
friend Your;
};
class Your
{
public:
My m;
void fun()
{
m.a = 10;
m.b = 10;
m.c = 10;
}
};
Static Members
- Static variables are static data members of a class belongs to a class that doesn’t belong to an object, and all the objects can share it.
- When you declare a static members inside the class, that data member must also be declared outside the class using scope resolution.
- You can access the static members by object or class.
- Static member functions can access only static data members of a class.
- 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
33
34
35
36
37
38
39
40
41
42
43
44
45
46#include <iostream>
using namespace std;
class Test
{
public:
int a;
static int count;
Test()
{
a = 10;
count ++;
}
static int getCount()
{
// a++; // invalid
return count;
}
};
int Test::count = 0;
int main()
{
Test t1, t2;
cout << t1.count << endl;
cout << t2.count << endl;
t1.count = 25;
cout << t2.count << endl;
cout << Test::count << endl;
cout << Test::getCount() << endl;
cout << t1.getCount() << endl;
return 0;
}
====OUTPUT====
2
2
25
25
25
25
Inner / Nested Class
- Inner Class can access the members of the outer class if they are static.
- Outer Class can access all the members of the inner class and create a object of the inner class.
- Example.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18class Outer
{
public:
void fun()
{
i.display();
}
class Inner
{
public:
void display()
{
cout << "Display of Inner" << endl;
}
};
Inner i;
};
Section 18: Exception Handling
Exception Handling
- Error types and solutions.
- Syntax Error - Compiler
- Logical Error - Debugger
- Runtime Error - Caused by (1) bad input (2) problem with resources, using Exception to solve.
Exception Handling Construct
- 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#include <iostream>
using namespace std;
int main()
{
int a = 10, b = 0, c;
try
{
if (b == 0)
throw 20;
c = a / b;
cout << c;
}
catch (int e)
{
cout << "Divided by zero " << "error code " << e << endl;
}
cout << "Bye" << endl;
return 0;
}
====OUTPUT====
Divided by zero error code 20
Bye
Throw and Catch Between Functions
- Error can also be implemented by if else, but the most powerful thing in try catch function is that you can throw the error from other functions.
- 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
33#include <iostream>
using namespace std;
int division(int x, int y)
{
if (y == 0)
throw 1;
else
return x / y;
}
int main()
{
int a = 10, b = 0, c;
try
{
c = division(a, b);
cout << c << endl;
}
catch (int e)
{
cout << "Divided by zero " << "error code " << e << endl;
}
cout << "Bye" << endl;
return 0;
}
====OUTPUT====
Divided by zero error code 20
Bye
All About Throw
- You can throw anything, such as int, float, string, etc.
- You can define your own Exception class. Example.
1
2
3class MyException : exception
{
}; - Using
throw
after the function to declare the throw type.1
2
3
4
5
6int division(int x, int y) throw (int)
{
if (y == 0)
throw 10;
return x / y;
}
All About Catch
- You can have multiple catch blocks.
...
means catch all, but it can only use in the last block. If you use...
in the first catch block, it will catch all of errors in the first block.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18try
{
... int
... float
... myException
}
catch(int e)
{
}
catch(myException e)
{
}
catch(...)
{
} - Try catch can do nesting.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15try
{
try
{
}
catch (int e)
{
}
}
catch (int e)
{
} - If you write your own Exception class, the child class must put before the base class. Here is an 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#include <iostream>
using namespace std;
class MyException1
{
};
class MyException2 : public MyException1
{
};
int main()
{
try
{
}
catch (MyException2 e)
{
}
catch (MyException1 e)
{
}
return 0;
}
Disclaimer
I took this course from Udemy, which is Learn C++ Programming -Beginner to Advance- Deep Dive in C++. I only took some notes of this amazing course for my personal future uses and share my thoughts with my peers. If you like it, you should take the course from Udemy too.