And something very important too.
Please use
override and
final specifiers.
override make compiler to check if your function really override something from base class and if not give error.
virtual void memberFunction() override
Or you can make simple mistake like this one and a long time to wonder what's going on:
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
|
#include <iostream>
using namespace std;
class A{
public:
A();
~A();
virtual void memberFunction();
virtual void memberFunction(int);
private:
};
class B : public A{
public:
B();
~B();
//Do you see little mistake I make
virtual void memberFunctions();
using A::memberFunction;
private:
};
template<class t>
void doAThing(t);
int main(){
A one;
B two;
doAThing(one);
doAThing(two);
system("pause");
return 0;
}
template<class t>
void doAThing(t one){
one.memberFunction();
}
A::A(){
}
A::~A(){
}
void A::memberFunction(){
cout << "from A" << endl;
}
void A::memberFunction(int one){
cout << "from A int" << endl;
}
B::B(){
}
B::~B(){
}
//This can be automaticlly generete,
//for example by Visual Studio
//and your 's' mistake
//will spread without notice
void B::memberFunctions(){
cout << "from B" << endl;
}
| |
Using
override and it will not compile:
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
|
#include <iostream>
using namespace std;
class A{
public:
A();
~A();
virtual void memberFunction();
virtual void memberFunction(int);
private:
};
class B : public A{
public:
B();
~B();
//Do you see little mistake I make
virtual void memberFunctions() override;
using A::memberFunction;
private:
};
template<class t>
void doAThing(t);
int main(){
A one;
B two;
doAThing(one);
doAThing(two);
system("pause");
return 0;
}
template<class t>
void doAThing(t one){
one.memberFunction();
}
A::A(){
}
A::~A(){
}
void A::memberFunction(){
cout << "from A" << endl;
}
void A::memberFunction(int one){
cout << "from A int" << endl;
}
B::B(){
}
B::~B(){
}
//This can be automaticlly generete,
//for example by Visual Studio
//and your 's' mistake
//will spread without notice
void B::memberFunctions(){
cout << "from B" << endl;
}
| |
Also you can use
final specifier to tell compiler that any attempt to override, for this example A::memberFucntion(int) in derived classes will be prevent and compiler will give error.
so this:
1 2 3 4 5 6 7 8
|
class A{
public:
A();
~A();
virtual void memberFunction();
virtual void memberFunction(int) final;
private:
};
| |
will give error here:
1 2 3 4 5 6 7 8 9 10 11
|
class B : public A{
public:
B();
~B();
//Do you see little mistake I make
virtual void memberFunction() override;
// You can't override A::memberFunction(int) final
virtual void memberFunction(int) override{};
using A::memberFunction;
private:
};
| |
P.s. Most developers believe that the use of these specifiers
override and
final are unnecessary luxury. But when I see a code written without their use I already know : "
This programmer is a gambling type. He/she is inclined to create very nasty bugs and can embitter the lives of everyone around him/her.". So if I'm the Boss, and you come to me for a job interview and I saw that you did not use
override I will say you goodbye without even thinking about it.
Someone may consider this to be extreme. For example, I can give you a task to do two classes. One abstract class A with empty destructor, and one derived from it, class B also with empty destructor - one pure virtual function f in A, and override f in B:
This is what I don't want to see:
1 2 3 4 5 6 7 8 9 10 11 12 13
|
class A
{
public:
virtual void f() = 0;
~A(){};
};
class B : public A
{
public:
virtual void f() {};
~B(){};
};
| |
This is what I will admire:
1 2 3 4 5 6 7 8 9 10 11 12 13
|
class A
{
public:
virtual void f() = 0;
virtual ~A(){};
};
class B : public A
{
public:
virtual void f() override {};
virtual ~B(){};
};
| |
Everyone can make mistakes. But smart people are making efforts to reduce the chance of making such mistakes.