国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > C++ > 正文

C++之普通成員函數(shù)、虛函數(shù)以及純虛函數(shù)的區(qū)別與用法要點

2020-05-23 14:17:41
字體:
供稿:網(wǎng)友

本篇文章主要介紹了C++中的普通成員函數(shù)、虛函數(shù)以及純虛函數(shù),非常的詳細(xì),有需要的朋友可以參考下

普通成員函數(shù)是靜態(tài)編譯的,沒有運(yùn)行時多態(tài),只會根據(jù)指針或引用的“字面值”類對象,調(diào)用自己的普通函數(shù);虛函數(shù)為了重載和多態(tài)的需要,在基類中定義的,即便定義為空;純虛函數(shù)是在基類中聲明的虛函數(shù),它可以再基類中有定義,且派生類必須定義自己的實現(xiàn)方法。

假設(shè)我們有三個類Person、Teacher、Student它們之間的關(guān)系如下:

C++之普通成員函數(shù)、虛函數(shù)以及純虛函數(shù)的區(qū)別與用法要點

類的關(guān)系圖

普通成員函數(shù)

【Demo1】

根據(jù)這個類圖,我們有下面的代碼實現(xiàn)

 

 
  1. #ifndef __OBJEDT_H__ 
  2. #define __OBJEDT_H__ 
  3.  
  4. #include <string> 
  5. #include <iostream> 
  6.  
  7. class Person 
  8. public
  9. Person(const string& name, int age) : m_name(name), m_age(age) 
  10.  
  11. void ShowInfo() 
  12. cout << "姓名:" << m_name << endl; 
  13. cout << "年齡:" << m_age << endl; 
  14.  
  15. protected
  16. string m_name; //姓名 
  17. int m_age; //年齡 
  18. }; 
  19.  
  20.  
  21. class Teacher : public Person 
  22. public
  23. Teacher(const string& name, int age, const string& title) 
  24. : Person(name, age), m_title(title) 
  25.  
  26. void ShowInfo() 
  27. cout << "姓名:" << m_name << endl; 
  28. cout << "年齡:" << m_age << endl; 
  29. cout << "職稱:" << m_title << endl; 
  30.  
  31. private
  32. string m_title; //職稱 
  33. }; 
  34.  
  35. class Student : public Person 
  36. public
  37. Student(const string& name, int age, int studyId) 
  38. : Person(name, age), m_studyId(studyId) 
  39.  
  40. void ShowInfo() 
  41. cout << "姓名:" << m_name << endl; 
  42. cout << "年齡:" << m_age << endl; 
  43. cout << "學(xué)號:" << m_studyId << endl; 
  44.  
  45. private
  46. int m_studyId; //學(xué)號 
  47. }; 
  48.  
  49. #endif //__OBJEDT_H__ 

測試代碼:

 

 
  1. void test() 
  2. Person* pPerson = new Person("張三", 22); 
  3. Teacher* pTeacher = new Teacher("李四", 35, "副教授"); 
  4. Student* pStudent = new Student("王五", 18, 20151653); 
  5. pPerson->ShowInfo(); 
  6. cout << endl; 
  7. pTeacher->ShowInfo(); 
  8. cout << endl; 
  9. pStudent->ShowInfo(); 
  10. cout << endl; 
  11. delete pPerson; 
  12. delete pTeacher; 
  13. delete pStudent; 

結(jié)果:

姓名:張三

年齡:22

姓名:李四

年齡:35

職稱:副教授

姓名:王五

年齡:18

學(xué)號:20151653

說明:

這里的ShowInfo就是一個普通的函數(shù)。pPerson、pTeacher和pStudent三個對象調(diào)用ShowInfo分別展示自己的信息。

我們知道:父類的指針是可以指向子類的對象的。我們把上面的測試代碼稍微改一下:

【Demo2】

 

 
  1. void test() 
  2. Person* pPerson = new Person("張三", 22); 
  3. Person* pTeacher = new Teacher("李四", 35, "副教授"); 
  4. Person* pStudent = new Student("王五", 18, 20151653); 
  5. pPerson->ShowInfo(); 
  6. cout << endl; 
  7. pTeacher->ShowInfo(); 
  8. cout << endl; 
  9. pStudent->ShowInfo(); 
  10. cout << endl; 
  11. delete pPerson; 
  12. delete pTeacher; 
  13. delete pStudent; 

結(jié)果:

姓名:張三

年齡:22

姓名:李四

年齡:35

姓名:王五

年齡:18

這時,pTeacher和pStudent只輸出了姓名和年齡,并沒有輸出子類所具有的特性(職稱和學(xué)號)。這應(yīng)該不是你期望的結(jié)果,你可能期望pTeacher和pStudent輸出老師和學(xué)生的完整信息,這時就需要用虛函數(shù)。

虛函數(shù)

我們把Person中的ShowInfo成員改成虛函數(shù)(在前面加上virtual),代碼如下:

【Demo3】

 

 
  1. class Person 
  2. public
  3. Person(const string& name, int age) : m_name(name), m_age(age) 
  4.  
  5. virtual void ShowInfo() 
  6. cout << "姓名:" << m_name << endl; 
  7. cout << "年齡:" << m_age << endl; 
  8.  
  9. protected
  10. string m_name; //姓名 
  11. int m_age; //年齡 
  12. }; 

在執(zhí)行上面【Demo2】中的測試代碼,得到我們想到的結(jié)果:

姓名:張三

年齡:22

姓名:李四

年齡:35

職稱:副教授

姓名:王五

年齡:18

學(xué)號:20151653

虛函數(shù)用法要點:

虛函數(shù)的聲明方式:virtual RETURN_TYPE functionName(ARGS 參數(shù)列表);

虛函數(shù)作用:現(xiàn)實C++中的多態(tài),進(jìn)行動態(tài)綁定(父類指針可指向子類的對象),直到運(yùn)行時才知道要調(diào)用哪個版本(哪個類定義)的函數(shù);

我們必要對虛函數(shù)進(jìn)行定義;

一旦父類的成員函數(shù)聲明virtual,其子類的函數(shù)不管有沒有聲明為virtual,都是虛函數(shù);

如果虛函數(shù)使用默認(rèn)實參,父類和子類定義的默認(rèn)實參最好一致。

【Demo4】:針對第4點說明:

 

 
  1. class Person 
  2. public
  3. Person(const string& name, int age) : m_name(name), m_age(age) 
  4.  
  5. virtual void ShowInfo() 
  6. cout << "姓名:" << m_name << endl; 
  7. cout << "年齡:" << m_age << endl; 
  8.  
  9. string GetName(); //正確,普通函數(shù)如果不被使用,可以只有聲明沒有定義 
  10. virtual int GetAge(); //錯誤,虛函數(shù)必須要有定義,即使是一個空實現(xiàn),因為編譯器無法確定會使用哪個函數(shù) 
  11.  
  12.  
  13. protected
  14. string m_name; //姓名 
  15. int m_age; //年齡 
  16. }; 

【Demo5】:針對第5點進(jìn)行說明:

設(shè)計我們的類如下定義。

 

 
  1. class Person 
  2. public
  3. virtual void SetAge(int age = 0) 
  4. m_age = age; 
  5. //... 省略 
  6. }; 
  7.  
  8.  
  9. class Teacher : public Person 
  10. public
  11. virtual void SetAge(int age = 1) 
  12. m_age = age; 
  13.  
  14. //... 省略 
  15. }; 
  16.  
  17. class Student : public Person 
  18. public
  19. virtual void SetAge(int age = 2) 
  20. m_age = age; 
  21.  
  22. //... 省略 
  23. }; 

測試1:

 

 
  1. void test() 
  2. Person* pPerson = new Person("張三", 22); 
  3. Teacher* pTeacher = new Teacher("李四", 35, "副教授"); 
  4. Student* pStudent = new Student("王五", 18, 20151653); 
  5. pPerson->SetAge(); 
  6. pTeacher->SetAge(); 
  7. pStudent->SetAge(); 
  8.  
  9. pPerson->ShowInfo(); 
  10. cout << endl; 
  11. pTeacher->ShowInfo(); 
  12. cout << endl; 
  13. pStudent->ShowInfo(); 
  14. cout << endl; 
  15. delete pPerson; 
  16. delete pTeacher; 
  17. delete pStudent; 

結(jié)果:

姓名:張三

年齡:0

姓名:李四

年齡:1

職稱:副教授

姓名:王五

年齡:2

學(xué)號:20151653

測試2:

 

 
  1. void test() 
  2. Person* pPerson = new Person("張三", 22); 
  3. Person* pTeacher = new Teacher("李四", 35, "副教授"); 
  4. Person* pStudent = new Student("王五", 18, 20151653); 
  5. pPerson->SetAge(); 
  6. pTeacher->SetAge(); 
  7. pStudent->SetAge(); 
  8.  
  9. pPerson->ShowInfo(); 
  10. cout << endl; 
  11. pTeacher->ShowInfo(); 
  12. cout << endl; 
  13. pStudent->ShowInfo(); 
  14. cout << endl; 
  15. delete pPerson; 
  16. delete pTeacher; 
  17. delete pStudent; 

結(jié)果:

姓名:張三

年齡:0

姓名:李四

年齡:0

職稱:副教授

姓名:王五

年齡:0

學(xué)號:20151653

純虛函數(shù)

在上面的例子中,我們假設(shè)所有的人都要工作,但不同的人工作的方式不同。于是我們就要強(qiáng)制要求繼承自Person的子類都要有工作的方法,這就需要純虛函數(shù)。定義如下:

【Demo6】

 

 
  1. class Person 
  2. public
  3. //... 省略 
  4. virtual void DoWork() = 0; 
  5. //... 省略 
  6. }; 

但此時我們編譯

 

 
  1. Person* pPerson = new Person("張三", 22); 

這句話時會報錯:error C2259: ‘Person' : cannot instantiate abstract class

這是因為我們并沒有為Person實現(xiàn)DoWork方法,而包含純虛函數(shù)的類是一個抽象的類,抽象類不能被實例化。

于是我們在子類中對它實現(xiàn)如下:

【Demo7】

 

 
  1. class Teacher : public Person 
  2. public
  3. //... 省略 
  4. virtual void DoWork() 
  5. cout << "教書..." << endl; 
  6. //... 省略 
  7. }; 
  8.  
  9. class Student : public Person 
  10. public
  11. //... 省略 
  12. virtual void DoWork() 
  13. cout << "學(xué)習(xí)..." << endl; 
  14. //... 省略 
  15. }; 

沒用DoWork方法:

 

 
  1. void test() 
  2. Person* pTeacher = new Teacher("李四", 35, "副教授"); 
  3. Person* pStudent = new Student("王五", 18, 20151653); 
  4.  
  5. pTeacher->DoWork(); 
  6. cout << endl; 
  7. pStudent->DoWork(); 
  8. cout << endl; 
  9.  
  10. delete pTeacher; 
  11. delete pStudent; 

結(jié)果:

教書…

學(xué)習(xí)…

純虛函數(shù)用法要點:

純虛函數(shù)的聲明方式:virtual RETURN_TYPE functionName(ARGS 參數(shù)列表) = 0;

含有純虛函數(shù)的類是一個抽象的類,抽象類不能被實例化。

包含純虛函數(shù)的抽象類常用來當(dāng)作對外的接口,說明這個類有什么功能,而沒有具體的實現(xiàn),基體的實現(xiàn)交由子類完成。

通過以上對普通成員函數(shù)、虛函數(shù)以及純虛函數(shù)的介紹,希望可以對大家有所幫助。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 洛浦县| 凯里市| 车险| 石门县| 克东县| 铁岭县| 涡阳县| 皋兰县| 陈巴尔虎旗| 策勒县| 永德县| 扬州市| 会同县| 绍兴市| 年辖:市辖区| 七台河市| 沙田区| 新龙县| 高淳县| 衡阳县| 闵行区| 余江县| 天等县| 江川县| 特克斯县| 惠安县| 宁乡县| 博乐市| 上饶县| 无锡市| 茌平县| 都匀市| 隆昌县| 湖北省| 丹东市| 合作市| 长兴县| 集安市| 湖南省| 靖安县| 柳州市|