C++学习一览~

我学 C++ 编程

  • 入门
    • 命名空间
      • 解决命名冲突
      • 库里的代码都在std命名空间
      • namespace()
        • 普通定义
        • 嵌套
        • 命名空间可以合并
      • 使用
        • 命名空间::成员
        • using 命名空间::成员
        • using namespace 命名空间:不建议使用,会导致命名空间污染,导致多个命名空间中的变量命名冲突
    • 函数重载
      • 函数名相同,参数不同
        • 个数不同
        • 参数类型不同
        • 顺序不同
        • 返回值不能作为函数重载的标记
      • C语言不支持函数重载
        • 函数名修饰规则:name maniging, _函数名
      • C++支持
        • 函数名修饰规则:函数名+参数,不同的版本实现不一样,Linux:_Z+函数名+参数,VS:@类名,命名空间@函数名@参数乐行:YZH@
    • 引用
      • 语法:一个变量的别名,不分配空间
      • 底层实现:与指针的实现方法相同
      • 做函数的参数或者返回值,效率比传值高
        • 函数返回值:返回变量的声明周期至少大于调用函数的声明周期
      • 引用和指针的区别
        • 引用在定义时必须初始化,指针可以不初始化
        • 有多级指针,没有多级引用
        • 有空指针,没有空引用
        • sizeof(引用):变量的大小,size(指针):指针大小
        • ++:引用++时变量本身的值++,指针++是指针向后便宜一个类型的地址
    • inline
      • inline函数名
      • 一般会在调用的地方展开
        • 简单的代码编译器直接展开
        • 如果较长,或者有循环,递归逻辑,编译器不会展开
        • 和宏函数相比:有语法检查,比宏函数安全,一般会用内联函数代替宏函数
      • 不支持分离编译,声明和定义放在一起
    • C++11
      • auto:类型的占位符
        • 定义auto变量,需要有初始化表达式,编译器通过初始化表达式推导变量类型
        • 不能使用auto的地方
          • 不能作为函数形参
          • 不能定义数组
          • 不能定义类的非静态成员变量
          • 不能作为模板的参数
  • 类和对象
    • 什么是类
      • 把数据和函数打包定义在一起的结构
      • 定义的类不占空间
      • 可以看做一个设计图纸
    • 类的实例化
      • 定义一个类类型的变量
      • 对象模型
        • 只存放普通成员变量
        • 大小遵循内存对齐的原则
        • 空类对象占1一个字节
    • 类的访问和权限关键字
      • 公有
        • public
          • 在类外直接访问
      • 私有
        • private
          • 在类外不能访问
        • protect
          • 在类外不能访问
      • 关键字在类内部不起作用,相对于类外成员的访问限制,类内部所有成员可以直接访问
    • this指针
      • 只存在于成员函数内部,势函数的第一个参数
      • 类类型 *const
      • 始终指向当前调用函数的对象
    • 6大成员函数
      • 构造函数
        • 函数名和类型相同,无返回值,可以重载
        • 初始化列表
          • 成员变量定义的地方
          • 成员变量初始化的顺序和定义的顺序相同,与在初始化列表中的顺序无关
          • 必须在初始化列表中初始化的成员
            • 引用
            • const成员
            • 没有默认构造的自定义成员
        • 默认构造
          • 无参构造
          • 全缺省构造
          • 编译器默认生成的构造
          • 默认构造只能存在一个,一般会定义一个全缺省构造
          • 如果没有定义构造,编译器会默认生成,如果已定义,编译器不会再生成默认构造
          • 构造函数会调用自定义成员的默认构造函数,完成自定义成员的初始化
        • 对于内置类型成员,空的构造函数不会初始化
        • 构造函数在实例化对象的时候,编译器自动调用
      • 拷贝构造
        • 函数名和类名相同,参数必须为引用类型,如果传值会造成无穷递归
        • 用已有对象创建一个新的对象时,编译器自动调用
        • 类型变量(对象),类型 变量 = 对象
        • 现代写法
          • 在初始化列表中初始化成员
          • 函数内部调用构造函数创建一个临时对象
          • 用过swap和临时对象交换成员变量
      • 析构
        • ~类名()
        • 完成资源清理工作
        • 对象生命周期结束,编译器自动调用
        • 不能重载
      • 赋值运算符重构函数
        • 运算符重载函数
          • 函数名:operator+运算符
            • 定义方式和普通函数没有区别,有参数,返回值
            • 不能重载的运算符:, * ? :: sizeof
            • 定义为成员函数时,实际的参数比运算符本身需要的参数个数少一个,第一个传入的参数始终为this指针,编译器自动传入this指针
        • operator=(参数)
        • 返回值:引用,返回值用来作连续赋值
        • 检查是否自己给自己赋值
        • 返回*this
        • 现代写法
          • 代码复用
          • 参数传值,传参时引发拷贝构造,创建一个临时对象
          • 使用swap完成和临时对象成员变量的交换
          • 临时对象的声明周期结束时,调用析构完成原有空间释放
      • 取地址运算符重载
        • 非const函数
        • const函数
        • 一般不需要重写,直接使用编译器自动生成的
        • 函数内部返回:this
    • const
      • 成员函数中,const实际上修饰的this指针,成员函数内部不能修改成员变量的值
      • const成员函数不能调用非const成员函数
      • 非const成员可以调用const成员函数
      • const对象不能调用非const成员函数
      • 非const对象可以调用所有成员函数
    • static成员
      • 成员变量存放在静态数据区
      • 成员变量必须在类外初始化
      • 成员变量全局只有一个,所有对象共享
      • 成员函数
        • 没有this指针
        • 函数内部不能调用非静态成员函数
        • 非静态成员函数可以调用静态成员函数
    • 友元
      • 友元函数
        • friend函数()
        • 可以突破封装,访问对象的私有成员
        • 一般不建议使用
        • 重载<<,>>运算符时用友元
      • 友元类
        • friend class 类名
          • 友元关系单向的
          • 友元关系不能传递
          • 通过对象.访问所有成员
        • 内部类
          • 具有友元类的所有特性
          • 对于外部类的static,枚举可以直接访问
          • 是一个独立的类,不从属于外部类,外部类对于内部类没有优越的访问权限
          • sizeof(外部类):外部类的大小,不包含内部类
  • 内存管理
    • 内存分布
      • 系统内核
        • 函数局部变量
        • 动态开辟的空间
      • 数据段
        • 全局数据
        • 静态数据
      • 代码段
        • 可执行代码(机器码)
        • 文字常量
    • C语言内存管理
      • malloc
      • calloc
        • 申请空间,按字节初始化为0
      • realloc
        • 原始空间如果小于重新申请的空间
          • 如果原始空间尾部有赋予的空间满足,直接修改底层标记
          • 否则,重新申请一片更大的空间,拷贝原始空间的内容,释放原有空间
        • 否则
          • 直接修改底层标记
    • C++内存管理
      • new, new[],delete, delete[]
      • new
        • 内置类型
          • operator nw–>malloc+异常
        • 自定义类型
          • operator new -->malloc+异常–> 构造函数
        • operator new VS malloc
          • malloc只申请空间,空间申请失败,返回NULL
          • operator new空间申请失败,抛异常
        • operator new
          • 定制自定义类型空间申请的方式,通过重写operator new实现,不影响其它类型的空间申请方式
      • delete
        • 内置类型
          • operator delete -->free
        • 自定义类型
          • 析构函数–>operator delete–>free
        • operator delete
        • 定制自定义类型空间释放的方式,通过重写operator delete实现,不影响其它类型的空间释放方式
      • new定位表达式
        • new(类型指针)构造函数(参数)
        • 显示调用构造函数,完成与分配空间的内容初始化
    • 面试题
      • 如何创建只在栈上创建对象的类
        • 第一种方式
          • 构造函数私有
          • 提供公有的静态方法,在方法内部调用够赞函数创建对象
        • 第二种方式
          • 禁止new,delete关键字的调用
            • 只声明不实现 operator new,operator delete
            • 或者声明operator new,operator delete为delete函数,C++11方式
      • 如何创建能在堆上创建对象的类
        • 构造函数私有化
        • 提供公有的静态方法,方法内部通过new关键字在堆上创建对象
        • 拷贝构造只声明,不实现,或者拷贝构造,构造声明为delete函数(C++11方式)
      • 单例模式
        • 饿汉模式
          • 程序运行之前对象已创建
            • 声明一个静态的成员变量,它的类型为当前类本身,在类外初始化,调用构造函数初始化
            • 构造函数私有
            • 拷贝构造私有,只声明不实现,或者声明为delete函数
            • 提供一个公有的静态方法,返回值为指针或者引用
          • 优点:简答,没有线程安全问题,多线程对效率要求较高的情况下使用
          • 缺点:启动慢,不能定义多个单例的初始化顺序
        • 懒汉模式
          • 在第一次使用对象的时候创建
            • 声明一个静态的成员指针,指针类型为当前类本身,在类外初始化为nullptr
            • 构造函数私有化
            • 拷贝构造私有化,只声明不实现
            • 提供一个公有的静态方法,方法内部通过调用new在堆上创建对象,返回指针
            • 通过加锁保证线程安全,保证全局只创建一个对象
              • double check
                • 内部检查是为了保证线程安全
                • 外部检查是为了提高效率
                • if(_sinptr == nullptr){_mtx.lock();if(_sinptr == nullptr){_sinptr == new 类名()} _mtx.unlock(); } return _sinptr;
          • 优点:启动快,延迟加载,可以定义多个单例的初始化顺序
          • 缺点:设计复杂,需要考虑线程安全问题
  • 模板
    • 函数模板
      • 模板实例化
        • 显示实例化
          • 函数名 <类型1, 类型2>
        • 隐式实例化
          • 函数名,编译器根据输入参数进行类型推演
      • 非模板函数和模板函数的匹配规则
        • 如果实际的参数类型和非模板函数完全匹配,则不再进行模板实例化,直接调用非模板函数
        • 如果实际参数类型和非模板函数不完全匹配,此时,模板如果可以生成根据匹配的函数,则进行实例化
        • 如果指定显式实例化,无论对应的非模板函数是否存在,都要进行模板函数的实例化过程
      • 特化
        • 当基础的模板函数实例化的函数不能正确处理某些类型的逻辑,则需要对特定类型定制特化版本
        • 如果特化版本实现比较复杂,或者有一些奇怪的编译错误时,建议定义一个普通函数进行处理
    • 类模板
      • 实例化
        • 必须显式实例化
      • 特化
        • 全特化
          • template <> class 类名<特化类型1, 特化类型2,…>
        • 偏特化
          • 部分特化
            • template class 类名 <T, 特化类型1,…>
          • 对参数作进一步限制
            • template <class T1, class T2> class 类名<T1*, T2*>
        • 类型萃取
          • 基础类模板和特化版本的结合应用
          • 区分内置类型和自定义类型
          • struct _trueType{}; struct _falseType{};
          • 基础类模板
            • template TypeTraits{typedef _falseType _isPodType}
          • 内置类型特化
            • template <> TypeTraits <内置类型> {typedef _trueType _isPodType};
  • STL
    • 容器
      • string
        • 管理字符顺序表,typedef basic_string string
        • 构造,拷贝构造,赋值,析构
        • 迭代器
          • begin(), cbegin()
            • 返回第一个字符所在位置
          • rbegin(), crbegin()
            • 返回最后一个字符的一个位置
          • end(), cend()
            • 返回最后一个字符的下一个位置
          • rend(), crend()
            • 返回第一个字符的前一个位置
          • 类似于指针
            • 解引用
              • 获取字符内容
            • ++
              • 移动到下一个字符的位置
              • 移动到上一个字符的位置
            • 其他
        • 访问
          • operator[]
            • 可读可写
            • 本质上为成员函数char& operator[](size_t pos)的调用
          • 迭代器
            • 可读可写
          • 基于范围for
            • 可读可写
            • 本质为底层通过迭代器的形式访问
        • 增删改查
          • +=
            • += char
            • += 字符串
            • += string
          • pop_back()
          • insert()
            • 可以在任意一个位置插入元素
            • 效率低,除过尾插,其它位置时间复杂度为O(n)
          • erase()
            • 可以在任意位置删除
            • 效率低,除过尾删,其他位置时间复杂度为O(n)
          • find()
            • 查找字符在string中的位置,如果找不到,返回npos
          • substr()
            • 构建子串string
        • 容量
          • resize
            • 改变有效字符的数量
            • 可能会引起增容:当n>size,引起增容
          • reserve
            • 只增容,不减少容量
            • 增容逻辑:初始大小一般为15字节,后续一般是2,1.5增加
        • 拷贝
          • 浅拷贝
            • 字节序拷贝,值拷贝,补考被自愿,值拷贝对象模型中的内容
          • 深拷贝
            • 即拷贝对象模型中的内容,如果有资源,一起拷贝
          • 写时拷贝
            • 浅拷贝+引用次数
      • vector
        • 管理各种类型的顺序表
        • 迭代器
          • 失效问题
            • 插入
              • 增容导致迭代器原来指向的位置已经被释放,无法访问
              • 插入操作之后,重新获取迭代器
            • 删除
              • 迭代器访问越界
              • 获取删除借口的返回值,返回值表示的是下一个元素的位置
        • 成员变量为三个指针
          • T* _start
            • 为begin()的返回值
          • T* _finish
            • 为end()的返回值
          • _endOfStorage
            • 当前申请的空间的最后一个位置的末尾,通过_endOfStorage -_start表示容量
        • 拷贝
          • 内置类型
            • 通过字节拷贝,即memcpy(),效率高,时间复杂度O(1)
          • 自定义类型
            • 调用自定义类型的拷贝构造或者复制运算符重载完成深拷贝,效率一般,时间复杂度O(n)
      • list
        • 带头循环的双向链表,可以存放各种类型的数据
        • 非原生迭代器实现
          • 通过封装节点实现迭代器
          • 解引用
            • T& operator(){return node_data}
          • ++,–
            • 前置++
              • self & operator++(){ node = node -> _next; return *this;}
            • 后置++
              • self operator++(int)(self tmp(*this); node = node -> _next; return tmp;)
            • 前置–
              • self&operator–(){node = node->_prev; return *this;}
            • 后置–
              • self operator–(int){self tmp(*this); node = node ->_prev; return tmp;}
          • !=,==
            • 直接比较节点的位置是否相同
          • ->
            • 获取节点中存放数据的成员,T*–>成员
            • T* operator->(){return &(_node->_data); 或者 return &operator *{}}
        • 迭代器失效
          • 删除
            • 删除的节点空间被释放,迭代器指向的位置无效
            • 获取迭代器返回值,返回值指向下一个节点的位置
        • list和vector区别
          • vector连续空间,list非连续空间
          • vector空间利用率高,不会造成内存碎片,list容易造成额你村碎片,空间利用率较低
          • 对方问效率要求高,不需要经常进行插入删除操作,vector比较合适,需要频繁的插入删除,对访问效率要求较低的情景,list比较合适
          • vector插入和删除都可能导致迭代器失效,list删除会导致迭代器失效
          • vector除过尾插尾删,其他位置插入删除的时间复杂度为O(n),list:在任何地方插入和删除的时间复杂度都是O(1)
          • vector支持随机访问,list不支持
          • vector迭代器实现方式:原生指针,list迭代器实现方式:非原生指针
      • deque
        • 实现方式:中控+buffer
        • 中控
          • 指针数组
        • buffer
          • 实际存放元素的空间
          • 每个buffer 的大小定长
        • 增容
          • buffer
            • 开辟空间,把空间的首地址存放在中控的指针数组中
          • 中控
            • 开辟新的更大的空间,把原有指针数组中的内容通过字节拷贝的方式一次拷贝,释放原有指针数组的空间,容器中存放的元素不需要拷贝
        • 特点
          • 兼容了list和vector部分优势
          • 增容代价小
          • 支持随机访问
          • 空间利用率高,不会造成内存碎片
          • 头插、尾插、头删、尾删时间复杂度都为O(1)
          • 物理上不连续,逻辑上连续的数据结构
        • 迭代器
          • start–成员
            • T*first–指向buffer的第一个位置
            • T*last–指向buffer最后一个位置的末尾
            • T*cur指向第一个buffer 的第一个元素的位置
            • T**node 指向中控中的第一个位置
          • finish–成员
            • T*first 指向buffer的第一个位置
            • T*last 指向buffer最后一个位置的末尾
            • T*cur 指向最后一个buffer的最后一个元素的下一个位置
            • T**node 指向中控中的一个位置
    • 迭代器
      • 正向迭代器
      • 反向迭代器
      • const迭代器
    • 容器适配器
      • 适配器:把一种容器,通过封装,转换成另一种容器,本质:实现转换
      • stack
        • FILO:后进先出
        • 底层结构
          • deque:默认
            • 尾插尾删时间复杂度为O(1)
            • 增容代价小
            • 不会造成内存碎片
          • vector
          • list
        • 底层结构需要实现规定的接口
          • pop_back
          • push_back
          • back
          • empty
          • size
        • 不提供迭代器
      • queue
        • FIFO:先进先出
        • 底层结构
          • deque:默认
          • list
        • 底层结构需要实现规定的接口
          • pop_back
          • push_back
          • back
          • empty
          • size
        • 不提供迭代器
      • priority_queue
        • 按照某种比较规则存放元素,每次出根元素
        • 底层结构
          • vector:默认
          • deque
        • 底层结构需要实现规定的接口
          • pop_back
            • 交换第一个和最后一个元素
            • 调用pop_back
            • 向下调整:保证堆的性质(最大堆或最小堆)
          • push_back
            • 调用pusha_back
            • 向上调整:保证堆的性质
          • front
          • empty
          • size
        • 不提供迭代器
    • 仿函数
      • 也称为仿函数对象:在类中重载"()"运算符
      • 和某些容器(比如priority_queue)或者算法(比如排序)配合使用,完成内部的元素的排列或者比较逻辑
    • 空间配置器
    • 算法
      • algorithm
        • sort
        • find
        • 其它
  • IO
    • 标准IO
      • cin
        • 通过>>把控制台保存到内置类型当中
          • istream对于内置类型,重载了“>>”
        • 对于自定义类型,可以重载运算符“>>”,通过cin>>自定义类型对象,把控制台内容存放到自定义对象中
      • cout、cerr、clog
        • 通过<<把内存中的内置类型内容输出到控制台
          • ostream对于内置类型,重载了"<<"
        • 对于自定义类型,可以重载运算符“<<”,通过cout,cerr,clog<<自定义类型对象,把内存中自定义对象的内容输出到控制台
    • 文件IO
      • ifstream
        • 二进制读入
          • 按照内存的存放形式读入,按字节读取,字节流读取
        • 文本读入
          • 对二进制内容经过编码之后的字符进行读入,按字符读取,字符流读取
        • 重载>>运算符
      • ofstream
        • 二进制写出
          • 按照内存的存放形式写出,按字节写,字节流写出
        • 文本写出
          • 对二进制内容经过编码之后的字符进行写出,按字符写出,字符流写出
        • 重载<<运算符
        • 二进制写出
        • 文本写出
        • 重载<<运算符
  • 7
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值