/* 阅读本示例,请持怀疑的态度!本示例可直接运行。
***********************************************************
** 接口继承:纯虚函数;实现类,可以是虚函数,也可以是普通函数
** 类继承:有虚函数, 普通函数,
** 虚函数的多态,
** 普通函数的隐藏调用:基类和派生类的同名方法
** 建议:子类的函数名称尽可能不要与基类的同名,没事别显摆!!!
***********************************************************
** 注意构造函数与析构函数,折构函数加上virtual
***********************************************************
** 基类的析构函数加virtual后,删除基类指针时,会先调用实际object的析构函数。
** 构造的顺序是:从里向外, 析构的顺序是:从外向里,想像成冬天穿衣服的顺序即可。
**---------------------------------------------------------
** 子类在delete时,会先执行本身的析构函数再执行基类析构函数。
** 在基类member function上加virtual关键字就是为了基类指针在指向派生类对象时,实际去调用派生类对应的member function(即多态)。
***********************************************************
** 接口:animal.h; 实现基类 people.h; 继承类 student.h; 再继续类 pupil.h;
*/
- main 函数与执行打印
-
#include <stdio.h> #include "people.h" #include "student.h" #include "pupil.h" int main(int argc, char const *argv[]) { int count = 0; printf("\r\n**1*********************inheritance demo count=%d *********************\r\n", ++count); People *p_people = new People(); //实现基类 p_people->run(); //实现接口:run ,虚函数, 实现多态 p_people->breathe(); //实现接口:breath, 普通函数,可被继承类隐藏调用 p_people->handle(); //自定义普通函数 可被继承类隐藏调用 p_people->drink(); //自定义虚函数, 实现多态 delete p_people; p_people = nullptr; printf("\r\n**2*********************inheritance demo count=%d *********************\r\n", ++count); Student *p_student = new Student(); //继承类 p_student->run(); //继承类直接调用基类函数 p_student->handle(); //继承类调用与基类的同名普通函数, 称为函数隐藏调用,参考如下解释链接 p_student->People::handle(); //继承类这样调用基类被隐藏的同名普通函数,https://blog.csdn.net/qq_41035283/article/details/123115066 p_student->drink(); //继续类重写[override]基类的同名函数, 实现多态:不同对象可以不同的喝法,站着喝,坐着喝,躺下喝...... p_student->People::drink(); delete p_student; p_student = nullptr; printf("\r\n**3*********************inheritance demo count=%d *********************\r\n", ++count); People *p_base = new Student(); p_base->handle(); //此处调用的是基类People的方法 p_base->drink(); //此处调用的是子类Student的方法,原因是基类添加了virtual关健字, 实现了多态; delete p_base; p_base = nullptr; printf("\r\n**4*********************inheritance demo count=%d *********************\r\n", ++count); People *p_base2 = new Pupil(); p_base2->run(); //此处调用的是基类People的方法, 继承调用 p_base2->handle(); //此处调用的是基类People的方法 p_base2->drink(); //此处调用的是子类的方法,原因是基类添加了virtual关健字, 实现了多态; delete p_base2; p_base2 = nullptr; //观注:此处的析构LOG,建议将基类的析构函数前的virtual删除,一对比,就会发现神奇之处 printf("\r\n**5*********************inheritance demo count=%d *********************\r\n", ++count); People obj_people; obj_people.run(); obj_people.handle(); obj_people.drink(); printf("\r\n**6*********************inheritance demo count=%d *********************\r\n", ++count); return 0; } 执行结果分析: **1*********************inheritance demo count=1 ********************* People struct. People run. People breathe. People handle. People drink. People destruct. **2*********************inheritance demo count=2 ********************* People struct. Student struct. People run. Student handle People handle. Student drink People drink. Student destruct. People destruct. **3*********************inheritance demo count=3 ********************* People struct. Student struct. People handle. Student drink Student destruct. People destruct. **4*********************inheritance demo count=4 ********************* People struct. Student struct. Pupil struct. People run. People handle. Pupil drink Pupil destruct. Student destruct. People destruct. **5*********************inheritance demo count=5 ********************* People struct. People run. People handle. People drink. **6*********************inheritance demo count=6 ********************* People destruct.
- 纯虚函数类: 接口 Animal.h
-
#ifndef ANIMAL_H #define ANIMAL_H /* 接口類:一定是纯虚函数*/ class Animal { public: virtual void run() = 0; //動物都會移動: virtual void breathe() = 0; //动物都要呼吸 }; #endif
- 基类,实现接口 people.h
-
#ifndef BASE_CLASS_H #define BASE_CLASS_H /*人类接口实现类:实现动物接口*/ #include <stdio.h> #include "animal.h" class People : public Animal { public: People(); virtual ~People(); // 基类的析构函数加virtual后,删除基类指针时,会先调用实际object的析构函数 public: virtual void run(); // Animal的接口虚函数的虚方法实现,供子类实现多态,可重写override void breathe(); // Animal的接口虚函数的普通方法实现,子类可以直接调用,要么同名函数隐藏调用 /// // virtual void eat() = 0; //接口 是不能被實例化的 virtual void drink(); //虛函數是可以被實例化的,作用同run函数 void handle(); //普通函数, 同breathe函数 }; #endif #include "people.h" People::People() { printf("People struct.\r\n"); } People::~People() { printf("People destruct.\r\n"); } void People::run() { printf("People run.\r\n"); } void People::breathe() { printf("People breathe.\r\n"); } // void People::eat(){ printf("People eat.\r\n");} void People::drink() { printf("People drink.\r\n"); } void People::handle() { printf("People handle.\r\n"); }
- 继承类:student
-
#ifndef STUDENT_H #define STUDENT_H #include <stdio.h> #include "people.h" class Student : public People { public: Student(); virtual ~Student(); //基类的析构函数加virtual后,删除基类指针时,会先调用实际object的析构函数 void drink(); void handle(); }; #endif // STUDENT_H #include "student.h" Student::Student() { printf("Student struct.\r\n"); } Student::~Student() { printf("Student destruct.\r\n"); } void Student::drink() { printf("Student drink\r\n"); } void Student::handle() { printf("Student handle\r\n"); }
- 小学生类:pupil
-
#ifndef PUPIL_H #define PUPIL_H /* 小学生作为子类 继承 父类学生类 */ #include "student.h" class Pupil : public Student { public: Pupil(/* args */); virtual ~Pupil(); //基类的析构函数加virtual后,删除基类指针时,会先调用实际object的析构函数 void drink(); void handle(); private: /* data */ }; #endif #include "pupil.h" Pupil::Pupil(/* args */) { printf("Pupil struct.\r\n"); } Pupil::~Pupil() { printf("Pupil destruct.\r\n"); } void Pupil::drink() { printf("Pupil drink\r\n"); } void Pupil::handle() { printf("Pupil handle\r\n"); }
- 纯虚函数类