虚函数的使用 以及虚函数与重载的关系, 空虚函数的作用,纯虚函数->抽象类,基类虚析构函数使释放对象更彻底
为了访问公有派生类的特定成员,可以通过讲基类指针显示转换为派生类指针。
也可以将基类的非静态成员函数定义为虚函数(在函数前加上virtual)
1 #include<iostream> 2 using namespace std; 3 4 class base{ 5 public: 6 /*virtual*/ void who(){ //define this function to virtual will be normal 7 cout << "this is the class of base !" << endl; 8 } 9 }; 10 11 class derive1:public base{ 12 public: 13 void who(){ 14 cout << "this is the class of derive1 !" << endl; 15 } 16 }; 17 class derive2 :public base{ 18 public: 19 void who(){ 20 cout << "this is the class of derive2 !" << endl; 21 } 22 }; 23 int main(){ 24 base beseObject, *p; 25 derive1 obj1; 26 derive2 obj2; 27 p = &beseObject; 28 p->who(); 29 cout << "------------------------------" << endl; 30 p = &obj1; 31 p->who(); 32 ((derive1*)p)->who(); 33 cout << "------------------------------" << endl; 34 p = &obj2; 35 p->who(); 36 ((derive2*)p)->who(); 37 cout << "------------------------------" << endl; 38 obj1.who(); 39 obj2.who(); 40 int i; 41 cin >> i; 42 return 0; 43 }
两次结果比较: 没加virtual:;加virtual后:
与重载的关系:
1 #include<iostream> 2 using namespace std; 3 4 class base{ 5 public: 6 virtual void f1(){ //virtual function 7 cout << "f1 function of base " << endl; 8 } 9 virtual void f2(){ //virtual function 10 cout << "f2 function of base " << endl; 11 } 12 virtual void f3(){ //virtual function 13 cout << "f3 function of base " << endl; 14 } 15 void f4(){ 16 cout << "f4 function of base " << endl; 17 } 18 }; 19 20 class derive:public base{ 21 public: 22 void f1(){ //virtual function 23 cout << "f1 function of derive " << endl; 24 } 25 virtual void f2(int x){ //lose virtual characteristic 26 cout << "f2 function of derive " << endl; 27 } 28 //f3(){ //wrong, not the same return type 29 // cout << "f3 function of base " << endl; 30 //} 31 void f4(){ //normal overload 32 cout << "f4 function of derive " << endl; 33 } 34 }; 35 int main(){ 36 base obj1, *ptr; 37 derive obj2; 38 ptr = &obj1; 39 ptr->f1(); 40 ptr->f2(); 41 ptr->f3(); 42 ptr = &obj2; 43 ptr->f1(); 44 ptr->f2(); 45 ptr->f4(); 46 int i; 47 cin >> i; 48 return 0; 49 }
结果:
空虚函数在中间类里必须声明,以保证其后的派生类能使用该虚函数。建立一条从虚函数到派生类的虚函数路径。
1 #include<iostream> 2 using namespace std; 3 4 class base{ 5 public: 6 virtual void print(){ 7 cout << "calss base!" << endl; 8 } 9 }; 10 class son:public base{ 11 public: 12 virtual void print(){ //empty virtual class 13 } 14 }; 15 class grandson :public son{ 16 public: 17 void print(){ 18 cout << "calss grandson!" << endl; 19 } 20 }; 21 void show(base* b){ 22 b->print(); 23 } 24 int main(){ 25 base *pbase = new base; 26 son *pson = new son; 27 grandson *pgrandson = new grandson; 28 show(pbase); 29 show(pson); 30 show(pgrandson); 31 int i; 32 cin >> i; 33 return 0; 34 }
结果:
存虚函数与抽象类
1 #include<iostream> 2 using namespace std; 3 4 class shape{ //抽象类里必须有一个纯虚函数 5 public: 6 virtual float area() = 0; 7 }; 8 class triangle :public shape{ 9 protected: 10 float h, w; 11 public: 12 triangle(float hh, float ww){ 13 h = hh; w = ww; 14 } 15 float area(){ 16 return h*w*0.5; 17 } 18 }; 19 class rectangle :public shape{ 20 protected: 21 float h, w; 22 public: 23 rectangle(float hh, float ww){ 24 h = hh; w = ww; 25 } 26 float area(){ 27 return h*w; 28 } 29 }; 30 float total(shape* s[], int n){ 31 float sum = 0; 32 for (int i = 0; i < n - 1; i++) 33 sum += s[i]->area(); 34 return sum; 35 } 36 int main(){ 37 shape* s[2]; 38 s[0] = new triangle(3, 4); 39 s[1] = new rectangle(3, 4); 40 float sum = total(s, 2); 41 cout <<"total area is: "<< sum << endl;; 42 int i; 43 cin >> i; 44 return 0; 45 }
结果:算出总面积 为 6