C++_基础知识点_2

24 常成员函数

链接_视频

  • 用法: 在成员函数后增加const关键字修饰。int GetNum() const;
  • 作用: 无法修改数据成员,一般用来修饰Get函数。
  • 本质: 成员函数被const修饰后,this指针的类型由T* const变为const T* const,其中T* const表示该指针本身不能被修改,const T* const表示该指针本身和指针指向的内容均不能被修改。
  • 意义: 让编译器提醒开发者该函数不能修改类的成员变量,用于const对象(引用或指针)。
  • mutable关键字能够突破这种限制。mutable int m_num;

25 常成员变量及初始化列表

链接_视频

  • 初始化列表可以用于初始化普通成员变量和常成员变量。
  • 初始化列表通常是用来构造有参数额成员对象。

26 静态成员变量

链接_视频

  • 使用关键字static修饰。
  • 要单独的把实现写在类外。(.cpp
  • 默认会用0对该成员进行初始化。
  • 静态成员变量是同一个类的不同对象共用的。
  • 本质: 带类域的全局变量。

27 静态成员函数

链接_视频

  • 在头文件(.h)的函数名前面加上关键字static
  • 静态成员函数内部仅能够访问静态的成员变量。
  • 本质: 静态成员函数中没有this指针;静态成员函数实际上就是带类域的全局函数。
  • 使用static修饰的成员变量或成员函数,与类的对象是无关的,可通过类名::静态成员变量类名::静态成员函数直接访问。

28 单例模式

链接_视频
链接_blog

29 友元的实现及作用

链接_视频

  • 使用关键friend修饰。
  • 作用: 可以访问一个类的私有成员。
  • 分类: 友元全局函数;友元成员函数;友元类。
  • 缺点: 破坏了类的封装和数据的隐藏性。
  • 用途: 不推荐使用,在某些方面,如运算符重载和某些软件设计时可酌情使用。

30 虚析构函数的作用

链接_视频

  • 当存在继承时,将父类和子类的析构函数均通过virtual关键字定义为虚函数,可避免子类的析构函数未被调用。
    1
    2
    3
    4
    5
    6
    7
    8
    // 子类赋值给父类是安全的
    // 当子类和父类的析构函数不是虚函数时,在delete时子类的析构函数未被调用
    CParent* p = new CChild;

    delete p;
    // 等价于 <==>
    p->~CParent(); // 间接调用,查子类虚表,子类虚表第0项目--子类的析构
    free(p);

31 虚函数的多态性

链接_视频

  • 有点懵逼…
  • 普通的成员函数中,调用虚函数具有多态性。(间接调用,看虚表
  • 在构造函数中调用虚表,实际上是直接调用,所以没有多态。
  • 在构造函数中调用普通成员函数,该成员函数中有虚函数的间接调用,由于进入构造时,会为对象赋值为当前类的虚表,所以没有多态。

32 纯虚函数与抽象类

链接_视频

  • 在虚函数的后面加上= 0,表示该函数不需要实现代码,也代表该类不能实例化。
  • 纯虚函数如果没有实现,那么包含该纯虚函数的类是抽象类。
  • 抽象类不能实例化。
  • 接口类: 只是作为父类,规范子类对外使用的接口。(某些函数,可以是虚函数,不一定包含虚函数
  • 抽象类: 一定要包含某一个纯虚函数,并且没有被实现。
  • 纯虚析构一定要有实现。

33 多重继承

链接_视频

  • 同时具备多个父类的特点。
    1
    2
    3
    class CFather1 { };
    class CFather2 { };
    class Cchild : public CFather1, public CFather2 { };
  • 多使用类的组合,少使用多重继承。

34 菱形继承与虚继承

链接_视频

  • 菱形继承导致的爷类(hhhhh)中的数据成员和成员函数是多份的问题,可以通过虚继承来解决。
    1
    2
    3
    4
    class CGrandfather { };
    class CFather1 : virtual Public CGrandfather { };
    class CFather2 : virtual Public CGrandfather { };
    class CChild : public CFather1, public CFather2 { };

35 运算符重载

链接_视频

  • 定义: 重载已有运算符,赋于新的功能。
  • 方式: 成员函数重载;友元全局函数重载。
  • 特点: 不破坏原有运算符的功能;运算符的优先级不变;使用方式要保持不变。
  • 作用: 代码简洁。
  • 可以重载的运算符:
    + - * / % ^ & | ~
    ! = < > += -= *= /= %=
    ^= &= |= << >> >>= <<= == !=
    <= >= && || ++ -- [] () ->
    , new new[] delete delete[]
  • 不能重载的运算符:
    . :: ?: #
  • 运算符的重载本质是函数的调用。(operator=
  • newdelete并不是关键字,而是运算符。

36 cincout的奥秘

链接_视频_1
链接_视频_2

  • cout是类ostream的对象。
  • cin是类istream的对象。
  • endl是函数。
  • <<是一种运算符重载,重载了字符串,整型,endl等函数的指针。
    1
    std::cout << "Hello World!" << std::endl;

37 转换运算符

链接_视频

  • 运算符重载的优先级高于转换运算符号。

38 函数模板

链接_视频

  • 核心: 把某些类型(int, double … )当作是变量。
    1
    2
    3
    4
    template <typename T>
    T GetMin(T a, T b) {
    return a > b ? a : b;
    }
  • 函数模板的隐式实例化。(由编译器去猜测函数模板的类型
    1
    2
    GetMin(1, 2);
    GetMin(1.0f, 2.0f);
  • 显示实例化。
    1
    GetMin<int>(1, 2.0f);
  • 模板的特例化。
    1
    2
    3
    4
    template <>
    char* GetMin(char* a, char* b) {
    ...
    }

39 类模板

链接_视频

  • 类的声明和实现都要放在.h文件中。

40 异常处理

链接_视频

  • 捕捉运行时的错误。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    try {

    // 认为抛异常
    throw "Hello World!";
    }
    catch(···) {
    // ···表示所有类型的异常
    }
    catch(std::string){

    }
  • 版权声明: 本博客所有文章均采用 Apache License 2.0 许可协议。转载请注明出处!
  • © 2020-2021 Hang Liu
  • Powered by Hexo Theme Ayer
  • PV: UV: