{%hackmd @owenowenisme/hackmd-theme %}
# Some PD2 Note
### Cheat sheet
* override : To change to implementation of a function in derived class.
* final : Prevent class or function from being overriden.
### **Overloading vs Redefining**
Overloading means that the function with the same name but different Function signature.
Redefining means the function with samename within different class(Can have the same function signature).
### **Function Overloading**
``` cpp
int sum(double a,double b){
return a+b;
}
double sum(double a,double b){
return a+b;
}
```
Will lead to compile error :
```!
overload.cpp: In function ‘double sum(double, double)’:
overload.cpp:29:8: error: ambiguating new declaration of
‘double sum(double, double)’
double sum(double a, double b)
^~~~~~~~~
overload.cpp:24:5: note: old declaration
int sum(double, double)’
int sum(double a, double b)
^~~~~~~~~
```
Function signature contains:
* function name
* parameter count
* parameter type
* parameters ordering
So that the complier is able to tell the difference between same function name.
### **Redefinition**
```cpp
class Whatever{
public:
int var1=123;
int var2=456;
Whatever(int var1,int var2){
cout<<"whateverrr\n";
}
void getval(){
cout<<var1<<'\n';
protected:
int pro=1234;
private:
int priint=1;
};
class child : public Whatever{
public:
child(int var1,int var2) : Whatever(var1,var2){
cout<<"omggg\n";
}
void getval(){
cout<<pro;
}
};
```
The getval() was redefinition in child class so if access function like this (Ignore constructor output):
``` cpp
child chi(123,123);
chi.getval();
```
Result:
1234
But you can still access the base class function with scope resolution operator :
``` cpp
chi.Whatever::getval();
```
### **Virtual function**
```cpp!
class A {
public:
virtual void f1() { cout << "Class A" << endl; }
void f2() { cout << "Class A" << endl; }
virtual ~A(){}
};
class B : public A {
public:
virtual void f1() { cout << "Class B" << endl; }
void f2() { cout << "Class B" << endl; }
virtual ~B(){}
};
int main()
{
A *a = new B;
a->f1();
a->f2();
}
```
Result:
```
Class B
Class A
```
The pointer type of *a is A so even with new B the object are still using type A.
But with virtual, like f1() compiler will find the most derived descendant class and use it.
To easily memorized, with virtual go to the most derived class, without it just use the use the definition in the type you are referencing.
Virtual function pros and cons
* Pros
- More flexibility -> Can decide which definition to use based on calling object
* Cons
- Uses more storage
- Late binding -> program runs slower
### Increment & Decrement op Overloading
* Prefix - Standard overloading
* Postfix - need to add a int in parameter
```cpp!
class X{
public:
void operator++() { /*something*/ };// member prefix ++x
void operator++(int) { /*something*/ };// member postfix x++
};
class Y { };
void operator++(Y&) { /*something*/ }// non-member prefix ++y
void operator++(Y&, int) { /*something*/ };// non-member postfix y++
```
:::warning
You should write both prefix & postfix overloading for compiler won't recognize the one you didn't define.
:::
---
### References
[C++中 overload、redefine 和 override的含義和區別](https://blog.csdn.net/weixin_42145698/article/details/101862028)
[C++各種雜談--虛擬函式(virtual function)](https://yayaya6d.pixnet.net/blog/post/350055421)
[Stackoverflow-Difference between using virtual functions and redefining](https://stackoverflow.com/questions/15514763/difference-between-using-virtual-functions-and-redefining)
[比較安全的 C++ 虛擬函式寫法:C++11 override 與 final](https://kheresy.wordpress.com/2014/10/03/override-and-final-in-cpp-11/)