C++入门day4-面向对象编程(下)

前言:C++入门day3-面向对象编程(中)-CSDN博客


初识:继承特性

继承的基础语法

cpp 复制代码
class A{
public:
    int a;
};
class B:public A
{
public:
    int b;
};

B类通过继承A类后,内部会继承一个int变量 a:从下图我们可以看到,B类型的对象mb在通过点运算符访问成员时,自动提示有a成员变量,而且看提示(A::a)我们知道还是A类中的成员变量a,通过继承的手段,让子类也能拥有该成员变量。一般我们将A类称为基类,也叫做父类;B类称为派生类,也叫做子类。

继承的优劣

继承的好处

1.提高代码的可复用性:减少重复代码,避免代码冗余。

2.提高代码的可维护性:如果父类中的代码需要修改,不需要额外修改子类代码

3.为多态的实现奠定基础:通过继承可以实现不同子类对象对同一信号返回不同响应的功能

继承的弊端

1.破坏了子类的独立性:通过继承,子类与父类之间产生了紧密的耦合关系,当父类发生改变时,需要考虑子类功能是否受影响。

2.增加了程序的复杂性:如果程序中继承关系复杂的话,会削弱程序的可拓展性和可维护性

继承方式

C++中class的默认继承方式是private私有继承

下面给出父类代码,该模块后续子类都继承该父类

cpp 复制代码
class father{
private:
    int f1;
protected:
    int f2;
public:
    int f3;
};
公共继承

继承时使用pubic关键字,使继承方式变为公共继承。在此继承方式下,子类可以访问父类中所有的公共成员。

cpp 复制代码
class son1:public father{
/*
//隐藏代码
private:
    int f1;
protected:
    int f2;
public:
    int f3;
*/
public:
    int s1;
};
保护继承

继承时使用protected关键字,使继承方式变为保护继承。在此继承方式下,子类可以访问父类中的protected权限下的成员以及public权限下的成员,并将public权限缩小为protected权限

cpp 复制代码
class son2:protected father{
/*
//隐藏代码
private:
    int f1;
protected:
    int f2;
    int f3;
*/
public:
    int s2;
};
私有继承

继承时使用private关键字,使继承方式变为私有继承。在此继承方式下,父类中的所有成员都将变更权限为private继承到子类中。此时子类无法访问父类任何成员。

cpp 复制代码
class son3:private father{
/*
//隐藏代码
private:
    int f1;
private:
    int f2;
private:
    int f3;
*/
public:
    int s3;
};

总结:

1.变更权限是指继承过程的权限变更,父类本身成员的权限不变

2.继承只会缩小权限,不会增加权限

复习:

成员权限:

private:私有的,只能在该类内访问

protected:受保护的,该类及子类可访问

public:公共的,该类及子类可以访问,同时定义的对象也可以访问该权限下成员

继承中的对象模型:

继承后,私有成员只是隐藏了,一样会被继承到子类中。

通过sizeof(son)我们也可以得知类的大小为16个字节,是父类的三个int整型变量加上子类的int变量s。一共4*4=16个字节。所以size=16。

构造与析构的顺序

子类继承父类后,子类创建对象时,也会调用父类的构造函数,那么现在的问题就是,二者的顺序是怎么样的呢。

让我们实验一下就可以了。

结果显而易见,先调用了父类的构造函数,再调用子类的构造函数。先析构子类,再析构父类。这个过程其实就类似于一个入栈与出栈的过程。构造顺序非常容易理解:没有父亲哪来的儿子,再记住析构顺序与构造时相反即可,你也不用纠结为啥不是先创建先死亡。事实上,这种现象叫做栈解旋 。

总结:构造时,先父后子;析构时,先子后父。

同名成员问题

在继承时,难免会存在成员名一样的问题。例如父类中有一个成员变量name,子类也有一个成员变量name,那么遇到成员同名的问题,我们该怎么办呢?不要慌,我们有规定。

访问子类成员:直接访问

访问父类成员:指明作用域

例如:

cpp 复制代码
class father{
public:
     string name;
};
class son:public father{
public:
    string name;
};

int main(){
    son s;
    s.name;//访问子类name
    s.father::name;//明显访问的是父类name
    return 0;
}

尝试运行,通过。明显没有任何错误。

另外,我们说的不单是成员变量,包括成员函数,只要是成员访问方法都是一致的。

初始化参数列表的拓展使用

cpp 复制代码
class A{
public:

    A(int num){
        cout<<"int构造"<<endl;
    }
};
class B:public A{
public:
    B(int num):A(num){
        //如果父类没有无参构造
        //可以在子类的构造函数中
        //利用初始化列表调用父类的构造函数
        //可以完成对子类隐藏的父类成员变量的初始化
    }

};

多继承语法

C++允许一个类继承多个类

语法:class 子类 : 继承权限修饰符 父类1 , 继承权限修饰符 父类2 ......

多继承可能会引发父类中有同名成员的出现,需要加以作用域区分

C++实际开发中不建议使用多继承

特殊的菱形继承我们需要了解一下。不过我们会放在多态学习时讲解。实际的开发中,能遇到的像输入输出流的类的继承关系中就有菱形继承。这时候我们先简单的知道一下就可以了


谢谢大家!!

相关推荐
轻口味12 分钟前
命名空间与模块化概述
开发语言·前端·javascript
晓纪同学1 小时前
QT-简单视觉框架代码
开发语言·qt
威桑1 小时前
Qt SizePolicy详解:minimum 与 minimumExpanding 的区别
开发语言·qt·扩张策略
飞飞-躺着更舒服1 小时前
【QT】实现电子飞行显示器(简易版)
开发语言·qt
明月看潮生1 小时前
青少年编程与数学 02-004 Go语言Web编程 16课题、并发编程
开发语言·青少年编程·并发编程·编程与数学·goweb
明月看潮生1 小时前
青少年编程与数学 02-004 Go语言Web编程 17课题、静态文件
开发语言·青少年编程·编程与数学·goweb
Java Fans1 小时前
C# 中串口读取问题及解决方案
开发语言·c#
盛派网络小助手2 小时前
微信 SDK 更新 Sample,NCF 文档和模板更新,更多更新日志,欢迎解锁
开发语言·人工智能·后端·架构·c#
Chinese Red Guest2 小时前
python
开发语言·python·pygame
一棵星2 小时前
Java模拟Mqtt客户端连接Mqtt Broker
java·开发语言