多态
多态主要用于父类虚函数传递给子类 子类利用虚函数对父类的重写
这样父类就可以通过指针对子类的虚函数进行调用
父类不可以通过指针直接调用子类中的方法,需要子类利用虚函数调用子类中的成员变量或者函数才能对调用
这里引入了静态联编和动态联编
静态联编:在运行前 就知道运行什么函数 调用熟读比较快 但是不灵活c语言中经常运用
动态联编:利用指针找到虚函数 调用的时候才知道用那个函数 比较灵活 但是调用速度比较慢
拥有虚函数的对象中会有一个虚指针 这个指针指向虚函数表(存放虚函数的地址)
子类重写父类虚函数 区修改表中的地址
虚基类 为了重写虚函数 父类总虚函数可以不实现
纯虚函数就是在父类的虚函数中写=0 不写函数体 不能调用 virtual fun()=0;
拥有纯虚函数的类 虚基类/抽象类 没法定义对象 但是可以定义指针或者引用 可以派生新的类 子类纯虚数即可定义对象
在类中书写完整的数据+功能 参数只有一个传递对象的地址 不同对象传递不同的地址
传入内容 对象中的数据 若干成员个数
具体功能实现如下代码 多态.cpp
1 #include<iostream> 2 using namespace std; 3 class A 4 { 5 public: 6 void fun(){ 7 cout << "父类的fun函数" << endl; 8 } 9 virtual void fun2()//父类的虚函数fun2 10 { 11 cout << "父类的fun2虚函数" << endl; 12 } 13 virtual void play()//父类的虚函数play 14 { 15 cout << "执行虚函数play" << endl; 16 } 17 virtual bool compare(int a, int b){ 18 return a > b; 19 } 20 }; 21 class B :public A//继承A类 用于重写A类中的虚函数 22 { 23 public: 24 void fun() 25 { 26 cout << "子类的fun函数" << endl; 27 } 28 virtual void fun2() 29 { 30 cout << "重写父类的fun2函数" << endl;//和父类的fun2同名 可以不写virtual 31 } 32 virtual void play() 33 { 34 cout << "执行子类的play虚函数" << endl; 35 } 36 bool compare(int a, int b)//重写父类中的虚函数compare其中返回值不一样 37 { 38 return a < b; 39 } 40 41 }; 42 void test(A*p) 43 { 44 p->play();// 父类的指针调用子类的虚函数play 不需要知道play的具体作用 45 } 46 void bulletSort(int arr[], int len, A*p)//这个一个冒泡排序 47 //第三个参数运用类A调用一个不确定的指针 根据调用可以执行不同的操作 48 { 49 int temp; 50 for (int i = 0; i < len - 1; ++i) 51 { 52 for (int j = 0; j < len - 1; ++j) 53 { 54 if (p->compare(arr[j], arr[j + 1])) 55 { 56 temp = arr[j]; 57 arr[j] = arr[j + 1]; 58 arr[j + 1] = temp; 59 } 60 } 61 } 62 for (int i = 0; i < len; ++i) 63 { 64 cout << arr[i] << ' '; 65 } 66 cout << endl; 67 } 68 int main() 69 { 70 B b; 71 b.fun();//调用类B中的fun函数 是子类的fun函数 72 A*p = &b;//父类指针指向子类对象 73 p->fun();//p指针是父类的指针指向fun调用父类的fun函数 74 //优先匹配父类函数 75 //父类指针 指向子类对象(隐式类型转换) 那么只能访问继承自父类的成员 不能访问子类定义的新成员 76 A a; 77 78 test(&a);//这相当于一个usb接口 79 //设计代码的时候不需要管后面的内容具体的实现方式 80 test(&b); 81 int arr[10] = { 2, 3, 1, 3, 2, 6, 5, 7, 8, 0 }; 82 //定义一个数组方便使用冒泡进行排序 83 bulletSort(arr, 10, &a);//调用冒泡排序对数组进行排序 判定条件&a就是调用类A中的bool函数的返回值 84 bulletSort(arr, 10, &b);//&b是类b中的返回值 85 86 //直接new对象 87 A*p = new B;//调用子类构造B 因为是new B 88 //如果用p区调用函数 这里调用是子类的虚函数 89 delete p;//调用析构函数 先在父类进行虚函数声明 再对子类进行虚函数声明 90 91 cin.get(); 92 return 0; 93 }