zl程序教程

您现在的位置是:首页 >  后端

当前栏目

【C++快速上手】番外篇二、知识点总结(持续更新...)

C++知识点 快速 总结 更新 ... 持续 番外篇
2023-09-11 14:20:36 时间

一、重要概念

类访问修饰符

详细参考:【C++快速上手】十七、类访问修饰符(总结)

  • 类访问修饰符有三个:public、private、protected
  • 在不同类型的类中,访问不同的修饰符所修饰的成员权限,如下表所示:
类的类型访问public修饰的成员访问private修饰的成员访问protected修饰的成员
基类yesyesyes
派生类yesnoyes
外部类yesnono
  • 派生类访问基类中的成员变量只要是publicprotected直接写就行,跟访问自己的类一样

继承、重载和多态

详细参考:【C++快速上手】十六、继承、重载和多态(总结)

  • 继承依据已有的类来定义一个新类,已有的类称为基类(父类),新类称为派生类(子类)。
    • 多继承即一个子类可以有多个父类,它继承了多个父类的特性。C++ 类可以从多个类继承成员。
  • 重载类内):是同名不同参,调用时根据参数的不同决定调用哪一个函数。
  • 多态类间):是同名同(或不同)参数,调用时根据函数类型是虚函数还是普通成员函数决定调用哪一个。
    • 继承关系,且使用的是基类的指针指向子类的实例(对象),示例如下:
Shape *shape;
Rectangle rec(10,7);

shape = &rec;

构造函数与析构函数

详细参考:【C++快速上手】十八、类构造函数 & 析构函数(总结)

  • 构造函数只有1个参数(或虽然有个参数,但只有1个参数没有默认值)时,最好加上explicit,避免隐式转换。
    • 原则上应该在所有的构造函数前加explicit关键字,当你有心利用隐式转换的时候再去解除explicit,这样可以大大减少错误的发生。
  • 析构函数最好写成虚函数virtual
    • c++中有这样的约束:执行子类构造函数之前,一定会执行父类的构造函数;同理,执行子类的析构函数之后,一定会执行父类的析构函数,这也是为什么我们一直建议类的析构函数写成虚函数的原因
    • 参考《【C++快速上手】七、纯虚函数和抽象类学习笔记》中的“构造函数不能是虚函数,而析构函数可以是虚析构函数”

虚函数

详细参考:

①、【C++快速上手】七、纯虚函数和抽象类学习笔记

  • 虚函数是在基类中使用关键字 virtual 声明的函数。在派生类中重新定义基类中定义的虚函数时,会告诉编译器不要静态链接到该函数。
  • 纯虚函数(或抽象函数)是我们没有实现的虚函数!我们只需声明它,通过声明中赋值0来声明纯虚函数!
    • 纯虚函数即没有函数体的虚函数
  • 抽象类:包含纯虚函数的类,不能创建对象
    • 抽象类只能作为基类来派生新类使用不能创建抽象类的对象可以创建抽象类的指针和引用
    • 在抽象类中成员函数内可以调用纯虚函数,在构造函数和析构函数内部不能使用纯虚函数
    • 如果一个类从抽象类派生而来,它必须实现了基类中的所有纯虚函数,才能成为非抽象类
  • 重要知识点
    • 纯虚函数使一个类变成抽象类
    • 抽象类类型的指针和引用通常指向派生类的对象
    • 如果我们不在派生类中完全覆盖纯虚函数,那么派生类也会变成抽象类。
    • 抽象类可以有构造函数
    • 构造函数不能是虚函数,而析构函数可以是虚析构函数。
      • 当基类指针指向派生类对象并删除对象时,我们可能希望调用适当的析构函数。如果析构函数不是虚拟的,则只能调用基类析构函数。

②、【C++快速上手】八、C++虚函数的vptr与vtable学习笔记

  • C++的动态多态性是通过虚函数来实现的;为了实现虚函数,C ++使用一种称为虚拟表的特殊形式的后期绑定

  • 每个使用虚函数的类(或者从使用虚函数的类派生的类)都有自己的虚拟表(vtable

  • 编译器还会添加一个隐藏指向基类的指针,我们称之为vptr

  • 类指针调用函数通常使用->操作符;引用调用函数通常使用.操作符。

  • 两种实例与调用函数的方法

    • 通过指针:Base *pt = new Derived();,调用时通常是:pt->fun1();这样的形式
      • 使用new创建对象是创建在中的,必须要程序员手动的去管理该对象的内存空间
    • 直接实例:Base base,调用时通常是:pt.fun1();这样的形式
      • 不使用new创建对象时,对象的内存空间是在中的,其作用范围只是在函数内部,函数执行完成后就会调用析构函数,删除该对象
  • C++的动态多态性是通过虚函数来实现的。简单的说,通过virtual函数,指向子类的基类指针可以调用子类的函数。例如,上述通过基类指针指向派生类实例,并调用虚函数,将上述代码简化为:

Base *pt = new Derived(); // 基类指针指向派生类实例
cout<<"基类指针指向派生类实例并调用虚函数"<<endl;
pt->fun1();
  • 其过程为:
    • ①、首先,程序识别出fun1()是个虚函数;
    • ②、其次,程序使用pt->vptr来获取Derived的虚拟表;
    • ③、最后,它查找Derived虚拟表中调用哪个版本的fun1()。这里就可以发现调用的是Derived::fun1()。因此pt->fun1()被解析为Derived::fun1()

二、关键字

explicit 关键字

详细参考:【C++快速上手】二十、explicit(显式)关键字学习笔记

  • explicit关键字只能用于修饰只有一个参数的类构造函数,它的作用是表明该构造函数是显式的,而非隐式的,跟它相对应的另一个关键字是implicit,意思是隐藏的,类构造函数默认情况下即声明implicit(隐式)
    • explicit 修饰构造函数时,可以防止隐式转换和复制初始化
    • explicit 修饰转换函数时,可以防止隐式转换但按语境转换除外
    • 单参数(或虽然有多个参数,但只有1个参数没有默认值)的构造函数最好声明为explicit

  • 在基类中将被重写的成员函数设置为虚函数,其含义是:当通过基类的指针或者引用调用该成员函数时,将根据指针指向的对象类型确定调用的函数,而非指针的类型。

    • https://blog.csdn.net/u010802169/article/details/88537490
    • 只需将基类中的成员函数声明为虚函数即可,派生类中重写的virtual函数自动成为虚函数;
      在这里插入图片描述
      未将test()函数设置为虚函数前的执行结果:
      在这里插入图片描述
      将test()函数设置为virtual后,执行结果如下:
      在这里插入图片描述
  • 基类中的析构函数必须为虚函数,否则会出现对象释放错误。以上例说明,如果不将基类的析构函数声明为virtual,那么在调用delete p2;语句时将调用基类的析构函数,而不是应当调用的派生类的析构函数,从而出现对象释放错误的问题。

  • 含有纯虚拟函数的类称为抽象类,它不能生成对象。

  • 纯虚函数用来规范派生类的行为,即接口。