前言
本系列内容为程序媛学习C++时做的笔记。以代码为主,并备注了打印结果以及详尽的解释注释。希望对你有所帮助。
多态
动态多态:
虚函数:动态多态(程序的角度上:程序在运行期间才能确定调用哪个类的函数 == 动态多态的范畴)
#include "iostream"
using namespace std;
class Animal {
public:
virtual void eat() {
cout << "Animal eat food" << endl;
}
};
class Pig : public Animal {
public:
void eat() {
cout << "Pig eat food" << endl;
}
};
void eatTest(Animal *animal) {
animal->eat();
// cout<<"animal地址:"<<animal<<endl;//0x401aeb
}
int main() {
//版本1:
Pig *pig = new Pig();
// cout<<"pig地址:"<<pig<<endl;//0x401aeb
Animal *animal = new Animal();
eatTest(pig);
eatTest(animal);
//版本2:
Animal *an1 = new Pig();
Animal *an2 = new Animal();
an1->eat();
an2->eat();
//…省略delete
return 0;
}
打印:
Pig eat food //如果Animal的eat()不加virtual,这里打印Animal eat food
Animal eat food
Pig eat food
Animal eat food
静态多态
静态多态 (编译期已经决定,调用哪个函数了,这个就属于静态多态的范畴) 重载(静态多态)
#include <iostream>
using namespace std;
void add(int number1, int number2) {
cout << number1 + number2 << endl;
}
void add(float number1, float number2) {
cout << number1 + number2 << endl;
}
void add(double number1, double number2) {
cout << number1 + number2 << endl;
}
int main() {
add(10000, 10000);
add(1.9f, 2.8f);
add(545.4, 654.54);
return 0;
}
补充:Java多态
多态的存在有三个前提:
1.要有继承关系
2.子类要重写父类的方法
3.父类引用指向子类对象
多态分为:
1:静态多态性(重载/编译时多态)指的是程序在编译时,系统就能决定调用哪个函数,如重载。它是根据参数列表的不同来区分不同的方法。通过编译之后会变成两个不同的方法,在运行时谈不上多态。
2:动态多态性(重写/运行时多态)指在运行中才能动态确定操作指针所指的对象,主要通过虚函数和重写来实现。
"运行时多态"是指一个类函数的调用并不是在编译时刻被确定的,而是在运行时刻被确定的。由于编写代码的时候并不能确定被调用的是基类的函数还是哪个派生类的函数,所以被称为“虚”函数。
静态多态性:
add(int a);
add(int a,int b);
add(double a);
add(double a,double b);
动态多态性
public class A{ }
public class AB extends A{ }
public class AC extends A{ }
public class test{
go(A a);
}
注:
java类中普通成员函数就是虚函数。
C++虚函数/纯虚函数
都是为了实现”运行时多态”,实现同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果。在运行时,可以通过指向基类的指针,来调用实现派生类中的方法。
区别:
对于虚函数来说,基类可以有定义,子类可以没有定义,也就是可以不重写。
对于纯虚函数来说,基类必须无定义,子类必须有定义,也就是子类中必须重写。
如果一个类所有的函数,都是纯虚函数,就相当于 Java的接口了。
举例:
#include "iostream"
using namespace std;
class Animal { //有纯虚函数,相当于Java的抽象类;如果是全纯虚函数,相当于Java的接口。
public:
virtual void eat() = 0; //纯虚函数(继承的子类是必须重写的,否则子类就是抽象类。抽象类不能被实例化。)
virtual void poo() {} //虚函数
virtual void poo2(); //虚函数
void pee() {} //普通函数
};
class Pig : public Animal {
public:
void eat() { //不重写,“Pig pig;”编译报错:cannot declare variable 'pig' to be of abstract type 'Pig'
cout << "Pig eat food" << endl;
}
void poo2() { //不重写,“Pig pig;”运行报错:undefined reference to `Animal::poo2()'
cout << "Pig eat food" << endl;
}
};
int main() {
Pig pig;
return 0;
}
模板函数
template<typename T>
void addAction(T t1, T t2) {
cout << "模板函数:" << t1 + t2 << endl;
};
int main() {
addAction(1, 2);//3
addAction<string>("1", "2");//12
return 0;
}
继承时子父类“构造函数/析构函数”的执行顺序
#include "iostream"
using namespace std;
class Animal {
private:
int age;
public:
Animal(int age) : age(age) {
cout << "Animal 构造函数" << endl;
}
~Animal() {
cout << "Animal 析构函数" << endl;
}
};
class Chicken : public Animal {
public:
Chicken(int age) : Animal(age) {
cout << "Chicken 构造函数" << endl;
}
~Chicken() {
cout << "Chicken 析构函数" << endl;
}
};
int main() {
Chicken chicken(2);
return 0;
}
打印:
Animal 构造函数
Chicken 构造函数
Chicken 析构函数
Animal 析构函数
引用
感谢三位巨人的肩膀。
本文参考blog如下:
https://blog.csdn.net/wuqiuping695/article/details/49069779
https://zhidao.baidu.com/question/193872859.html
https://blog.csdn.net/Sunburst_Lf/article/details/91394642