多态性是指当类之间存在层次结构,并且类之间是通过继承关联时,此时调用成员函数,会根据调用函数的对象的类型来执行不同的函数。
多态性可分为静态多态性和动态多态性:
- 静态多态性,通过函数重载实现,在编译时系统就能知道要调用哪个函数,故而称之为静态多态性,又称之为编译时多态性。
- 动态多态性,通过虚函数实现,在编译时系统不确定调用哪个函数,而是在运行时才动态地确定,又称之为运行时多态性。
虚函数的作用是允许在派生类中重新定义与基类同名的函数,并且可以通过基类指针或引用来访问基类和派生类中的同名函数。这样,就突破了基类指针或基类引用不能访问派生类中成员的限制。
可以在基类声明纯虚函数,即在基类中仅声明一个函数而不定义具体功能,具体功能留给派生类根据需要去定义(当然也可以为纯虚函数定义具体实现,这时,派生类将不会继承该缺省实现而只会继承接口),声明形式为
virtual void show() = 0;
虚析构函数
新构建派生类的对象时,先构建基类对象,再构建派生类对象,当该对象生命周期结束时,会先调用派生类的析构函数,再调用基类的析构函数,也就是说,析构函数的调用顺序和构造函数的调用顺序相反。
但是,如果定义了一个基类指针且该指针指向派生类对象,在delete该指针的时候,只会调用基类的析构函数(将派生类对象赋值给基类对象,此时基类对象只能访问派生类的基类成员)。可以通过将基类的析构函数声明为虚析构函数,这样,就可以依据多态性调用派生类的虚析构函数,再调用基类的虚析构函数。
重写、重载、重定义
https://www.cnblogs.com/xinxue/p/5471708.html
C++继承与派生中关于函数的重写、重载、重定义:
- 重写(override),重写也称为覆盖,是指派生类重写基类中具有相同名称和参数的虚函数,函数特征相同,但具体实现不同。被重写的函数不能是static的,但必须是virtual的。
- 重载(overload),重载指在相同作用域中存在多个同名的函数,这些函数的参数列表不同,然后这些同名函数就成了不同的函数。不能通过返回类型来判断。
- 重定义,重定义也称为隐藏,派生类重新定义基类中具有的相同名称的非虚函数。如果一个派生类存在和基类相同的函数,则派生类的函数将覆盖基类的同名函数。只能在调用的时候强制转换为基类类型,或者使用域运算符才能调用被隐藏的基类的同名函数。
Person, Student, Worker, Docter
Person.h
//
// Created by kaim on 2022/1/29.
//
#ifndef LEARN_PERSON_H
#define LEARN_PERSON_H
#include <iostream>
using std::string;
class Person {
public:
Person(string&, bool, int);
string get_name() const;
bool get_sex() const;
int get_age() const;
virtual void show() const; // 声明为虚函数
protected:
string name;
bool sex;
int age;
};
class Student: virtual public Person { //公有继承,且声明Person是Student的虚基类
public:
Student(string&, bool, int, string&);
string get_university() const;
virtual void show() const override;
protected:
string university;
};
class Worker: virtual public Person {
public:
Worker(string&, bool, int, double);
double get_salary() const;
virtual void show() const override;
protected:
double salary;
};
class Doctor: public Student, public Worker {
public:
Doctor(string&, bool, int, string&, double, string&);
string get_doctorid() const;
virtual void show() const override;
protected:
string doctorid;
};
#endif //LEARN_PERSON_H
Person.cpp
//
// Created by kaim on 2022/1/29.
//
#include "Person.h"
#include <iostream>
using std::cout;
using std::endl;
Person::Person(string& name, bool sex, int age): name(name), sex(sex), age(age) {
}
string Person::get_name() const {
return name;
}
bool Person::get_sex() const {
return sex;
}
int Person::get_age() const {
return age;
}
void Person::show() const {
cout << "Person -- name: " << name << ", sex: " << sex << ", age: " << age << endl;
}
Student::Student(string& name, bool sex, int age, string& university): Person(name, sex, age), university(university) {
}
string Student::get_university() const {
return university;
}
void Student::show() const {
cout << "Student -- name: " << name << ", sex: " << sex << ", age: " << age << ", university: " << university << endl;
}
Worker::Worker(string& name, bool sex, int age, double salary): Person(name, sex, age), salary(salary) {
}
double Worker::get_salary() const {
return salary;
}
void Worker::show() const {
cout << "Worker -- name: " << name << ", sex: " << sex << ", age: " << age << ", salary: " << salary << endl;
}
Doctor::Doctor(string& name, bool sex, int age, string& university, double salayr, string& doctorid): Person(name, sex, age),
Student(name, sex, age, university),
Worker(name, sex, age, salayr),
doctorid(doctorid){
}
string Doctor::get_doctorid() const {
return doctorid;
}
void Doctor::show() const {
cout << "Doctor -- name: " << name << ", sex: " << sex << ", age: " << age << ", university: " << university <<
", salary: " << salary << ", doctorid: " << doctorid << endl;
}
main.cpp
void testclass4() {
//继承与派生,多态与虚函数
Person *p;
Student *s;
Worker *w;
Doctor *d;
string name = "kaim";
string uni = "university";
string id = "0001";
Person p1(name, true, 25);
Student s1(name, true, 25, uni);
Worker w1(name, true, 25, 600);
Doctor d1(name, true, 25, uni, 600, id);
d1.Person::show();
d1.Student::show();
d1.Worker::show();
d1.show();
p = &s1;
p->show();
p = &w1;
p->show();
p = &d1;
p->show();
}
int main() {
testclass4();
return 0;
}
output
Person -- name: kaim, sex: 1, age: 25
Student -- name: kaim, sex: 1, age: 25, university: university
Worker -- name: kaim, sex: 1, age: 25, salary: 600
Doctor -- name: kaim, sex: 1, age: 25, university: university, salary: 600, doctorid: 0001
Student -- name: kaim, sex: 1, age: 25, university: university
Worker -- name: kaim, sex: 1, age: 25, salary: 600
Doctor -- name: kaim, sex: 1, age: 25, university: university, salary: 600, doctorid: 0001