面向对象三大特性之多态(C++)
面向对象的三大特性是封装,继承和多态,本文主要介绍C++里的多态特性
在编译器把函数或模板连接生产执行代码的过程中,有两种联编方式,一种是静态联编,另外一种是动态联编,
静态联编是在编译阶段就把函数连接起来,就可以确定调用哪个函数或者模板,而动态联编是指在程序运行时才能确定函数和实现的连接,才能确定调用哪个函数
根据联编的方式我可以把多态(函数多种形态)分成两种,静态多态和动态多态,网上有些资料有四种,多出了宏多态和函数多态,但我个人认为这两种应该属于静态多态
动态多态
主要通过继承和虚函数实现,父类指针或者引用能够指向子类对象,调用子类的虚函数,所有在编译时是无法确定调用哪个虚函数,每个子类都维护着一张虚函数表,
程序执行时查询虚函数表来确定调用哪个虚函数;
1 #include <iostream> 2 using namespace std; 3 4 class Base 5 { 6 public: 7 virtual void Print() = 0; 8 virtual ~Base(){} 9 }; 10 11 class child_1 : public Base 12 { 13 public: 14 void Print() 15 { 16 cout << "child_1 Print function" << endl; 17 } 18 ~child_1() 19 { 20 cout << "child_1 destructor function" << endl; 21 } 22 }; 23 24 class child_2: public Base 25 { 26 public: 27 void Print() 28 { 29 cout << "child_2 Print function" << endl; 30 } 31 ~child_2() 32 { 33 cout << "child_2 destructor function" << endl; 34 } 35 }; 36 37 int main() 38 { 39 Base *p = new child_1; //父类指针指向子类对象 40 p->Print(); 41 delete p; //记住释放,否则内存泄露 42 p = new child_2; 43 p->Print(); 44 delete p; 45 p = NULL; 46 return 0; 47 }
存在这样的多态特性,所有最好是把类的析构函数定义成virtual类型,否则在释放时无法调用析构函数
静态多态
使用的是静态联编方式,在编译时函数和函数的实现就关联在一起,主要是通过重载和模板实现,在宏多态中,是通过定义变量,编译时直接把变量替换,实现宏多态.
1 #include <iostream> 2 using namespace std; 3 4 //宏多态;a,b可以不同类型 5 #define sum(a,b) ((a) + (b)) 6 7 class Base 8 { 9 public: 10 void Print() //不需要定义为虚函数 11 { 12 cout << "base Print() functions" << endl; 13 } 14 void Print(int val) //重载,根据参数列表不同实现函数多态 15 { 16 cout << "base Print(int) functions" << endl; 17 } 18 }; 19 20 class child : public Base 21 { 22 public: 23 void Print() //不需要定义为虚函数 24 { 25 cout << "child Print() functions" << endl; 26 } 27 void Print(int val) //重载,根据参数列表不同实现函数多态 28 { 29 cout << "child Print(int) functions" << endl; 30 } 31 32 }; 33 34 template<typename T> 35 void func(T &p) 36 { 37 p.Print(); 38 p.Print(1); 39 } 40 41 int main() 42 { 43 Base base ; 44 child ch; 45 int a = 23, b = 19; 46 double fa = 13.32, fb = 29.36; 47 func(base); 48 func(ch); 49 50 cout << sum(a,b) << endl; 51 cout << sum(fa,fb) << endl; 52 return 0; 53 }