C++基础部分核心点笔记(自用)

  1. c++相对于c来说增加了面向对象的类概念,开发效率高
  2. 有一种叫引用的概念,本质是int * const p的指针,问就是大部分面向对象语言没有指针,为了削弱用户对内存的掌控。这样更安全(补充,NULL问题,可以中转赋值,但屏蔽了直接赋值)
  3. 比如,java和C++比的话,C++执行效率高,Java开发效率高,这些都是相对的,开发效率高往往意味着更方便的类,更简单的语法,更安全可维护的开发体系
  4. 引用的本质是拿取被引用物自身,这样理解就行,尤其重载那块
  5. C++中String是个自带的类,有别于int等基本数据类型
  6. C++使用内联函数代替宏定义的函数,成员函数默认内联
  7. 哑元:1.保持函数的向前兼容2.区分重载的函数
  8. ,是一个抽象概念,属性理解为数据成员、成员变量,行为理解成员函数,二者统称为成员,命名多用大驼峰(帕斯卡)
  9. 栈内存适合临时使用,堆需要销毁,但是,有时候可能出现仍可使用的情况,可以赋为NULL
  10. 封装类似于黑盒测试(白盒是暴露的测试,黑盒只关心输入输出)
  11. C++中字符串是ASCCI编码,如果做处理,不支持中文,但是仅显示,可以使中文,尽量避免。
  12. 默认构造函数也运行,即使没有内容,手写后不用,就会报错,可重载
  13. 初始化列表和内部赋值问题:const不能内部,列表执行效率更高,如果影响可读性,可以不适应,也可以混合使用两种,但很怪。
  14. 浅拷贝解决最暴力的方法:私有化屏蔽拷贝构造函数
  15. 有new必须要有delete(无其他内存控制时)
  16. 析构函数不能重载
  17. { }叫独立代码块:表示一个局部范围
  18. 重名有就近原则,名字空间可解决,但实际开发尽量减少重名
  19. ::匿名名字空间
  20. 代码规范https://docs.qq.com/pdf/DTWZMWmVyd3BGeUha?=undefined&_t=1689402940890&u=7ed1c4b6bb654f3c9422052add197900
  21. this指针,编译器会自动加,但重名问题必须手动加
  22. 链式调用,返回值是对象本身,需要返回*this
  23. Static关键字,构造和析构不能用,分静态成员(函数和变量)和静态局部变量,都是对象共用的,一般类内声明类外初始化(const修饰后可以类内,不太用)。静态局部变量,创建时定义,运行时开始,程序结束销毁;静态成员变量,创建前初始化。推荐类名::变量,来调用。静态成员函数没有this指针,所以没法调用同类非静态成员,但是可以调用同类中其他静态成员。Ps。静态类没法实例化,非静态可以调用静态。
  24. const关键字,一般认为常量。const成员函数,只能调用常数化函数,可以调用非const变量,但是不能更改其数值,建议只要类的成员函数不修改属性值就尽量使用常成员函数,以提升程序的安全性,例如getter等。常对象,不能改任何值,不能调用任何非const成员函数。Ps。Const常成员变量除了可以声明时赋值,还可以通过构造函数初始化列表实现赋值,因为构造在编译前完成,覆盖掉静态值。Const局部变量,表示不修改,尽量给参数、引用参数使用,引用参数应该在能被定义为const的情况下,尽量定义为const,这样可以达到引用的安全性。
  25. 友元可以破坏面向对象体系,能提高运行效率。慎用。主要用于运算符重载,其他地方别用!!!由于类外,没用this指针,所以不能产生副本,参数需要使用引用。本质是类外一般函数,不需要类名作用域。友元类,友元关系,不可继承,单向不具有交换性,不具有传递性。注意顺序。
  26. 运算符重载:本质:函数重载。不是所有都能重载。多种方式:1.友元函数运算符重载:单目有前后就注意占位符。2.
  27. 返回值本质是个局部变量!!!
  28. C++中布尔类型使用bool,使用数值true表示1,使用false表示0
  29. C++11的配置:QMAKE_CXXFLAGS += -std=c++11
  30. 赋值运算符只能用成员函数的方式重载,类似于拷贝构造,因为返回的是类引用,*this,而友元函数没有this。
  31. Shtring函数中,参数一是Char*是源字符串时,保留参数二个字符,而string是源字符串时,不保留参数二个字符
  32. 模板是支持参数化多态(像多态,但理论上不是)的工具,主要是参数、返回值的类型,进行通用算法
  33. 泛型编程:泛型编程是一种编程理念,其提出的动机是发明一种语言机制,能够在编程中编写完全一般化的可重复使用的算法,不会因为数据类型的不同而有差异。
  34. STL来自惠普实验室,在C++之前存在,被C++发扬,所有容器都属于std名字空间。容器指的是用来存储数据的集合,由于内部存储的数据使用模板实现,因此可以支持绝大多数数据类型。迭代器是配合容器进行高效遍历的工具,是一种特殊的指针。
  35. Vector和array(C++11引入)一样也是由数组实现,地址连续。是最常用的顺序容器,string例外。默认值是0(array不一定)。他们相同点是底层逻辑都是数组,地址连续存储;不同点是:array的长度有限、固定,vector是变长数据,不受长度限制,动态扩展。
  36. begin指向的是第一个元素,end指向的是最后一个元素的下一个;

Begin:返回一个当前vector容器中起始元素的迭代器。

End:返回一个当前vector容器中末尾元素下一个的迭代器。

Front:返回当前vector容器中起始元素的引用。

Back:返回当前vector容器中末尾元素的引用。

  1. list本质双向链表,高效插入删除,但随机存储效率低。不支持序号,只能通过迭代器指针。(不支持普通的for循环,但是支持for each)
  2. 迭代器:list<string>::iterator iter=lis.bigin(),使用advance来移动迭代器。
  3. Sort排序,数字按大小,字符按编码。
  4. Deque性能位于vector和list之间,基本支持所有API。
  5. 关联容器之间没有严格的物理关系,但内部有顺序关系,所以才能使用迭代器遍历,但不要这样用。
  6. 容器的遍历通常是迭代器进行,因为迭代器对容器遍历的兼容性最好,且遍历效率最高。迭代器是一种特殊的指针,如果要使用迭代器进行读写操作,可以使用iterator类型的迭代器;如果要使用迭代器进行只读操作,可以使用const_iterator类型的迭代器,因为只读迭代器的效率更高。
  7. 继承就是在一个已经存在的类的基础上建立一个新的类,并拥有其特性。
  8. 继承代码修改主要:函数隐藏和函数覆盖,还有函数新增
  9. 基类与派生类是相对的,一个类既可以作为基类,又可以作为派生类,取决于两个类之间的相对关系。间接继承也是继承。基类通常更加抽象,派生更具体。
  10. 类的构造函数和析构函数不能被继承!!
  11. 派生类的所有构造函数都必须直接或间接调用基类的任——个构造函数。

Son没有编写构造函数,编译器会自动添加一个无参的构造函数在无参构造函数中调用基类的无参构造参数。如果基类没有无参构造函数,可以使用两种已学的方法解决:

  1. 【函数重载】给基类一个手写的无参构造函数。
  2. 【默认参数】给基类有参构造设置参数的默认值。
  1. 派生类也可以通过编写代码的方式直接或间接调用基类的任意一个构造函数。

1.透传构造:直接参数列表调父类构造

2.委托构造:灵活的,但不能闭环,依赖透传

3.继承构造:继承构造并不是继承了构造函数,在C++11中,可以通过继承构造的语法,让派生类自动实现每个基类的构造函数,并且同样参数的构造函数进行透传。

  1. 对象的创建与销毁是比较消耗资源的,这也是为什么面向对象的程序运行效率较低的原因,但是编程效率得到了提升。为了开发降低运行效率。
  2. 大多变成语言都是单继承,但C++支持多继承。但多继承可能出现一些二义性(ambiguous)问题。
  1. 继承多个基类有同名成员,用::
  2. 菱形(钻石)继承,要么找直接基类;要么使用虚继承
  1. 虚继承(virtual):虚继承为继承的派生类对象生成虚基类表和虚基类指针,指针指向的是各自的虚基类表。
  2. 三种继承方式,市面大多public公有继承,理解的话,继承就是把继承过来的平级或低级权限,变成自己的继承的那个类型权限。
  3. 多态按照字面的意思就是"多种状态",可以简单地概括为“一个借口,多种状态”,程序在运行时才决定调用的函数内容,即同一个接口会根据传入参数的个体差异,而采用不同的策略。(比模板更聪明)
  4. 多态的实现要有三个前提条件:
  1. 要有公有继承
  2. 基类引用/指针指向派生类对象
  3. 派生类覆盖基类成员函数
  1. 虚函数(也是virtual):函数覆盖是通过虚函数实现的,用virtual关键字修饰成员函数,这样的成员函数就是虚函数,虚函数支持函数覆盖(而不是函数隐藏)。函数覆盖是使用多态的前提。

在C++11中可以通过override关键字来验证函数覆盖是否成功,只需要使用此关键字修饰派生类的新覆盖的函数即可。

成员函数使用:多态

析构函数使用:防止多态时内存泄露

  1. 虚函数的性质如下:
  1. 虚函数有传递性,当基类中某个成员函数设置为虚函数后,派生类中覆盖此函数的同名函数(函数名称相同、参数列表完全相同、返回值类型相关)——也自动变为虚函数。
  2. 只有成员函数和析构函数可以设置为虚函数。
  3. 如果成员函数声明与定义分离,只需要使用virtual修饰声明处即可。
  1. 基类指针指向派生类,只调用基类析构,派生类无法销毁,会发生内存泄漏。使用虚析构函数可以解决这个问题。在设计类时如果不写析构函数,编译器也会自动生成一个空的析构函数,如果这个作为基类,可能会在多态时存在内存泄漏的隐患,因此建议一个类的析构函数统一手写并设置虚析构函数,除非这个类不会作为其它类的基类。
  2. 动态类型绑定:多态之所以可以生效,是因为动态类型绑定的原理。

当一个类有虚函数时,这个类会生成一个虚函数表,记录所有虚函数,同时此类的对象中有一个隐藏的成员变量:虚函数表指针,这个成员变量指向本类的虚函数表(这个表也有继承,也有覆盖)。

当使用了基类的引用或指针指向派生类对象时,编译器会自动生成一段检查对象真正类型的代码,在程序运行时,通过对象的虚函数表指针去查找表中记录的虚函数的调用地址。

和虚继承一样,降低运行效率。QT中和多态、this指针使用联动。

  1. 抽象类只表示一个算法框架,没有对象,只能通过和多态联动来使用(*和&)。如果一个类中有纯虚函数,则这个类就是抽象类;如果一个类是抽象类,则这个类一定有至少一个纯虚函数。纯虚函数:只有声明,没有定义。写法:虚函数=0。抽象类的派生类如果把抽象类都覆盖了,就是实类,而没全覆盖就还是抽象类。
  2. 错误是编译时语法错误等产生的问题,异常是运行时的逻辑错误产生的的问题,如不处理,程序崩溃。处理异常分抛出和捕获。
  3. Inf:无限、无穷
  4. 标准异常家族:<stdexcept>
  5. 三大特点都降低运行效率。
  6. 智能指针类的使用需要引入头文件#include <memory>,另外,如auto_ptr:是C++98的概念,现在C++11已经弃用,原因主要是控制权转移后容易对原指针操作,产生错误。其他都是C++11的指针。unique_ptr:可以使用move函数完成控制权的转移,提升了语法门槛,降低无意中转移的概率,

share_ptr:共享share_ptr的资源,通过引用计数解决,当0时,则销毁释放,两种创建方式,new或则make_shared<class>(“name”)。两种方法各有利弊:make_shared效率更高,而且更加安全(极端情况),内存释放更慢,效率低。

weak_ptr:弱持有,不会影响销毁,协助share_ptr,需要expired判断是否为空。

  1. nullptr在C++11取代NULL,NULL宏定义的0,而nullptr是指针
  2. auto自动推导数据类型,但是不能用于参数类型和数组,方便,但是可读性差。
  3. decltype可以推导一个表达式的数据类型,在推导的过程总,编译器只会分析表达式计算的类型,不会实际计算表达式的值。
  4. Cout特殊输出。进制输出
  5. <iomanip>域管理
  6. <sstream>字符串流
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夢靈子DMC

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值