C++ 多态性和虚函数

多态性是指当类之间存在层次结构,并且类之间是通过继承关联时,此时调用成员函数,会根据调用函数的对象的类型来执行不同的函数。

多态性可分为静态多态性和动态多态性:

  • 静态多态性,通过函数重载实现,在编译时系统就能知道要调用哪个函数,故而称之为静态多态性,又称之为编译时多态性。
  • 动态多态性,通过虚函数实现,在编译时系统不确定调用哪个函数,而是在运行时才动态地确定,又称之为运行时多态性。

虚函数的作用是允许在派生类中重新定义与基类同名的函数,并且可以通过基类指针或引用来访问基类和派生类中的同名函数。这样,就突破了基类指针或基类引用不能访问派生类中成员的限制。

可以在基类声明纯虚函数,即在基类中仅声明一个函数而不定义具体功能,具体功能留给派生类根据需要去定义(当然也可以为纯虚函数定义具体实现,这时,派生类将不会继承该缺省实现而只会继承接口),声明形式为

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
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值