C++继承

1. C++继承原理

​ C++的继承可以理解为在创建子类成员变量之前先创建父类的成员变量,实际上,C语言就是这么模仿出继承功能的。

在内存中,父类的成员变量和子类的成员变量如图所示:

(1) C++子类对象的构造过程。先调用父类的构造函数,再调用子类的构造函数,也就是说先初始化父类的成员,再初始化子类的成员。

(2) 若父类没有默认的构造函数,子类的构造函数又未调用父类的构造函数,则无法编译。

(3) C++子类对象的析构过程。如果父类的析构函数不为虚函数,则只调用父类的析构函数,而不调用子类的析构函数,此时会产生内存泄露。如果父类的析构函数为虚函数,会先调用子类的析构函数,再调用父类的析构函数。且c++默认的析构函数不是虚函数

2. 虚函数介绍

(1)父类指针可以指向子类对象,这个是自然而然的,因为子类对象的内存前面就是父类成员,类型完全匹配。

(2) 当父类指针指向子类对象,且子类重写父类某一函数时。父类指针调用该函数,就会产生以下的可能

*该函数为虚函数:父类指针调用的是子类的成员函数。*

*该函数不是虚函数:父类指针调用的是父类的成员函数。*

例子:

  • 当只有子类的方法有virtual关键字,而父类方法没有时。调用的仍然是父类的成员方法。
  • 当子类的方法没有有virtual关键字,而只有父类方法有时。调用的是子类的成员方法。因为当父子类成员函数的形式相同时,父类成员方法有virtual关键字,会自动给子类方法也加上。

3.虚函数的注意事项:

(1) 子父类的虚函数必须完全相同,为了防止开发人员一不小心将函数写错,于是C++11添加了override关键字

(2)父类的析构函数必须为虚函数:这一点很重要,当父类对象指向子类对象时,容易使独属于子类的内存泄露。会造成内存泄露的严重问题。

例子:

4.虚函数实现多态的原理

(1) 动态绑定和静态绑定:

① 静态绑定:程序在编译时就已经确定了函数的地址,比如非虚函数就是静态绑定。

② 动态绑定:程序在编译时确定的是程序寻找函数地址的方法,只有在程序运行时才可以真正确定程序的地址,比如虚函数就是动态绑定。

(2) 虚函数是如何实现动态绑定的呢?

① 每个有虚函数的类都会有一个虚函数表,对象其实就是指向虚函数表的指针,编译时编译器只告诉了程序会在运行时查找虚函数表的对应函数。每个类都会有自己的虚函数表,所以当父类指针指向子类对象,引用的便是子类虚函数表,自然调用的就是子类的函数。

5.纯虚函数

纯虚函数介绍:

​ 当一个基类无实际意义,其中的函数作用都是被覆写时,那么纯虚函数的语法就能够在此起到作用。

​ 只要将一个虚函数写为纯虚函数,那么该类将被认为无实际意义的类,无法产生对象。纯虚函数也不用去写实际部分,写了编译器也会自动忽略。

​ 需要注意的是,构造函数和析构函数不能省。

例子:

posted @ 2023-05-03 00:16  曹剑雨  阅读(301)  评论(0编辑  收藏  举报