C++ 复习笔记

C++易考易混淆的知识点

一、C++ 引用 vs 指针

引用很容易与指针混淆,它们之间有三个主要的不同:

  • 不存在空引用。引用必须连接到一块合法的内存。
  • 一旦引用被初始化为一个对象,就不能被指向到另一个对象。指针可以在任何时候指向到另一个对象。
  • 引用必须在创建时被初始化。指针可以在任何时间被初始化。

 

二、void *

void* 是一种特殊的指针类型,可用于存放任意对象的地址。

一个 void* 指针存放着一个地址,这一点和其他指针类似。

在介绍 void 指针前,简单说一下 void 关键字使用规则:

  • 如果函数没有返回值,那么应声明为 void 类型;
  • 如果函数无参数,那么应声明其参数为 void;(常省略)
  • 如果函数的参数或返回值可以是任意类型指针,那么应声明其类型为 void* ;
  • void 的字面意思是“无类型”,void*则为“无类型指针”,void不能代表一个真实的变量,void体现了一种抽象。

void *有以下几个特点:

  1. 任何类型的指针都可以直接赋值给void指针, 且无需进行强制类型转换

  2. 如果要把 void 类型的指针赋值给其他类型的指针,需要进行显式转换
  3. void指针可以直接和其他类型的指针进行比较指针存放的地址值是否相同

  4. void指针只有强制类型转换后才可以正常对其操作。

             如果没有类型转换,那么就不清楚该地址中到底是什么类型的对象,因此不能直接操作 void* 指针所指的对象,也就无法确定能在这个对象上做哪些操作。

             也就是说一个 void 指针必须要经过强制类型转换以后才有意义。

         5. void指针变量和普通指针一样可以通过 NULL 或 nullptr 来初始化,表示一个空指针

         6. 当void指针作为函数的输入和输出时,表示可以接受任意类型的输入指针和输出任意类型的指针

             如果函数的参数或返回值可以是任意类型指针,那么应声明其类型为void*

 

三、多态

  1、重载实现编译时多态,虚函数实现运⾏时多态
  2、运行期多态的实现依赖于虚函数机制。
  当某个类声明了虚函数时,编译器将为该类对象安插一个虚函数表指针,并为该类设置一张唯一的虚函数表,虚函数表中存放的是该类虚函数地址。
  运行期间通过虚函数表指针与虚函数表去确定该类虚函数的真正实现。
 
  总结:运行期多态通过虚函数发生于运行期
 
  3、对模板参数而言,多态是通过模板具现化和函数重载解析实现的。以不同的模板参数具现化导致调用不同的函数,这就是所谓的编译期多态。
  

  运行期多态优点与缺点

  1. OO设计中重要的特性,对客观世界直觉认识。
  2. 能够处理同一个继承体系下的异质类集合。
  1. 运行期间进行虚函数绑定,提高了程序运行开销。
  2. 庞大的类继承层次,对接口的修改易影响类继承层次。
  3. 由于虚函数在运行期在确定,所以编译器无法对虚函数进行优化。
  4. 虚表指针增大了对象体积,类也多了一张虚函数表,当然,这是理所应当值得付出的资源消耗,列为缺点有点勉强。

  编译期多态优点与缺点

  1. 它带来了泛型编程的概念,使得C++拥有泛型编程与STL这样的强大武器。
  2. 在编译器完成多态,提高运行期效率。
  3. 具有很强的适配性与松耦合性,对于特殊类型可由模板偏特化、全特化来处理。
  1. 程序可读性降低,代码调试带来困难。
  2. 无法实现模板的分离编译,当工程很大时,编译时间不可小觑。
  3. 无法处理异质对象集合。

 四、虚函数表

  参考:https://leehao.me/C-%E8%99%9A%E5%87%BD%E6%95%B0%E8%A1%A8%E5%89%96%E6%9E%90/

五、const 与 volatile

   1、volatile关键字是一个类型修饰符,用它声明的类型变量表示可以被某些编译器未知的因素更改,比如:操作系统、硬件或者其它线程等。

  遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优化,从而可以提供对特殊地址的稳定访问;

  如果不使用valatile,则编译器将对所声明的语句进行优化。之所以优化是因为访问寄存器要比访问内存单元快得多。

  但是优化之后容易出现问题,例如现在要直接对内存地址单元的内容修改,如果继续使用未经过valatile声明的变量,则读到的值有可能是寄存器中未经过修改的值,

  但本意是要读发生变化后的数值,所以会出现意想不到的错误。而经valatile声明的变量,每次访问该变量时都会从内存单元中重新读取。

  2、const经常用于声明不希望被其它程序修改的常量;volatile经常用于声明因意外而可能发生改变的变量。

  

  下面具体分析两个变量的用法:

  1、const意味着“只读”。

  2、一个定义为volatile的变量是说该变量可能会被意想不到地改变,这样,编译器就不会去假设该变量的值了。

  精确地说,优化器在用到该变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。

 

posted @ 2022-03-07 16:56  零纪年  阅读(96)  评论(0)    收藏  举报