1、C++系统学习路径博客记录
1)C++学习-1(各种编译器,以及qt下使用qmake,cmake,linux下使用cmake管理)
C++学习-1(各种编译器,以及qt下使用qmake,cmake,linux下使用cmake管理)博博客内的知识大致介绍
一、基础C++
介绍了编译器,编译时选择C++版本、编译链等知识扩展
二;QT介绍安装
该节核心为;一个单纯的qt软件是没有用的,需要一整套的构建套件才能完成程序的编译,然而选择不同的构建套件就可以完成对相同程序的编译生成不同平台的可执行程序。
三、CMake
Cmake是makefile的一层封装,介绍他的基本使用。
C++学习 -2 namespace大全博客内的知识大致介绍
一、需具备的知识体系知识
1、编译链接
按行编译,之后链接主要是去寻找编译时说在外部的链接。
2、C语言中的常识
1)static;静态
修饰局部变量修改存储域从而修改生命周期、修饰全局变量限定外部链接属性只能当前文件使用
2)extern;表示该变量链接的时候去外部寻找。
3)小作用域优先于大作用域
3、引入C++中的namespace
1)命名空间的作用及用法
对全局变量和函数等成员在一定范围内链接属性的更改和控制、总而言之是通过命名空间名来控制链接属性,达到管理内部所有成员的链接属性。
2)同文件之间定义使用namespace
注意3点,声明保证编译时通过、使用的三种方法、以及定义否则链接时出错
3)不同C文件之间如何定义和使用namespace
注意;跨文件声明命名空间的成员要使用需要挨个声明
4)默认命名空间;也叫全局命名空间
::直接调用,省略也是可以的,冲突时仍然是小优先于大的原则
5)匿名命名空间
主要用于跨文件时,不让其他文件使用匿名空间中的元素,因为没有名字你也调用不到,类似于C中的static,限制了链接属性,让其他文件无法调用到。
6)嵌套命名空间
冲突时其实就是遵守小优先于大,调用就是按顺序写过来就行了
C++学习 -3 C和C++的混合编程及库的调用博客内的知识大致介绍
一;前导小知识;标准库
1、__Cplusplus宏
如果这个宏定义了则是g++编译反之gcc编译
2、为什么需要混合编程
有这样的需求存在,需要调用其他语言实现的库,那么此时就需要混合编程,否则可能用不了报错。
3、怎么才允许实现混合编程
混合是发生在链接的时候则保证链接的时候不出错升高生成可执行文件
4、如何解决c和C++的混合编程
extern “c”{
}目的就是告诉c加加编译器,接下来范围里面的才用c编译器的方式进行编译,则形成的函数中间名字也是采用c方式形成而不是c加加从而后来链接才能链接到一起去
二;C++与C的混合编程实战
1、如何混合编程;
混合编程的“混合”操作发生在链接这一步
2、C++和C混合编程的困难所在。
C++支持函数名重载,而C不支持,因此编译器生成目标文件时,函数名在目标文件中的临时内部名称规则不同。导致链接时符号对不上。
3、实验验证
(1)预备知识;
-c、只编译不链接。-E 只做预处理、-o指定生成文件名。objdump -d clib,o > clib.i 反编译将可执行程序逆向出汇编语言
(2)实验一;编译反编译;证明了C语言中名称为add的函数,编译后符号表中就叫add
(3)实验二;证明了C++语言中名称为add的函数,编译后符号表中叫_Z3addii;并且其重载机制的命名.
(4)实验三:证明使用extern “C”{
}则可以按C来编译从而可以链接成功
4、C和C++库调用;三种情况
(1)同一个项目全部有源码,一次编译链接。
C的头文件中加extern "C"声明
(2)同一个项目中C是库,C++是源码,C++调用C
C的头文件中加extern "C"声明,在C++中直接包含头文件调用即可
(3)同一个项目中C++是库,C是源码,C调用C++
需要自己来一层封装,将带来的.h文件封装一下,并且把新的.h文件添加上extern "C"声明;
4)C++学习 -4 查询C++标准库写应用层代码以filestream【缺少对标准库的解析】
C++学习 -4 查询C++标准库写应用层代码以filestream 博客内的知识大致介绍
1、查看C++标准库的三个方式
查看标准库的两个网址
英文老但是全;http://cplusplus.com/reference/fstream/basic_fstream/
中文并且更新到20;https://zh.cppreference.com/w/cpp/io/basic_fstream
2、根据C++标准库网页参考编写使用读写文件的filestream
5)C++学习-5 普查所有C++关键词对其全面了解(2万长文配合诸多案例进行讲解)
关键字;C++的字符类型char,wchar_t
1、char;字符类型
主要讨论char在C++不同版本中占字节情况以及是否有符号问题
2、wchar_t宽字符
C++新引入的可以多个字节存储Unicode编码,有对应的wcin和wcout来输入输出、和Wstring。
3、指定具体字节数的字符类型
char8_t (C++20 起) char16_t (C++11 起) char32_t (C++11 起)
关键字;剩余一些不太复杂的关键字
1、C++中无明显变化的关键字
与c语言作用一致的一些关键字
2、C++中新增的运算符代用关键字
1)逻辑运算代用关键字例如and &&
2)位运算代用关键字例如bitand &
3)不等判断运算符代用关键字例如not_eq !=
3、C++的bool关键字
C++原生支持的,而C语言是需要自己重定义
关键字;引用符号reference
1、引用类似于linux中符号链接
C++引入引用的目的是由于指针太危险了(可以直接修改),引用就是功能弱化安全性增加的底配板指针,其本质就是
const类型的指针
2、引用在c++中主要用在函数传参和返回值地方
表示可以标明只读参数,还是可写参数,表示参数类型是输入输出。
3、引用和sizeof关键字
sizeof引用得到的大小是引用关联变量的大小(注意继承中存在类型裁剪这个以类型裁剪为准的有图片实践验证的)
关键字;assert()断言、静态断言static_assert
1、C语言的assert
C语言中assert是运行时中断程序并向stderr打印信息,并且在运行时频繁调用极大影响运行效率,并且表达式出错会中断程序
2、C++ 的静态断言static_assert
其主要实现编译时的静态断言,表达式为假则编译报错并打印后接着的消息,表达式为真则没有影响。在C++中static_assert主要使用在用于检查模板参数是否合乎期望
3、实战案例
1)接static_assert检查定义的类是否符合表达式
2)板类中使用static_assert判断传入参数的合法性
3)使用模板template 和 typename 如何定义模板类以及定义模板类实类
关键字;enum枚举
1、在C语言中的enum,
定义时不能省略enum,除非typedef 重定义一下
2、在C++中的enum
与struct一致,定义时可以省略enum
3、枚举存在两个冲突问题
1)C++11中引入可以带类前缀的枚举
解决了不同枚举之间不能有相同的名字
2)枚举值不能与宏的名字一样 未解决
4、使用注意;
enum枚举类型与数据类型强转的时候是没有做保护的,枚举是有限范围的,如果超出范围也不会报错,使用需要使用的时候自己注意了
关键字;面向对象相关的一系列关键字;
1、继承机制
使用:来表示继承
2、virtual虚拟关键字
虚拟的,一般与动态运行时确定机制相关,如虚函数(用于多态),虚继承(解决多继承的二义性问题),虚析构函数(解决多态时new的对象释放调用析构函数问题,保证析构函数调用正确)
3、override 重写关键字
只是为了明确表明我是重写父类的虚函数方法,增加库制作者和调用则的协作
4、继承中止final
指定某个虚函数不能在子类中被覆盖,或者某个类不能被子类继承
5、using关键字的两个用法
1)命名空间的大包含声明
2)用于重新定义继承是访问权限问题
6、oprator
用于运算符重载时定义方法名时使用
引入的一个函数返回时隐藏调用拷贝构造函数的问题
7、friend 友元
1)友元函数;目的就是解决一个class外部的函数也能访问class内部受保护的成员变量也就是private类型的变量这是友元函数
2)友元类;批量创建友元函数的一种方法,将这个类的所有方法都变成友元方法,都可以去访问那个类的私有成员变量。
8、explicit 显示关键字
用来修饰只有一个参数的构造函数,以阻止构造函数不喝事宜的隐式的类型转换
关键字;模板相关的关键字temlate<>,typename、export
1、temlate<>用于定义一个模板
2、typename 用于表示用什么名字来暂时代替占位
3、export
专用于模板,类似于extern作用于简单类型一样的作用,用于导入
4、requires
C++20引入的 用于表示模板的参数约束,具体要用来在看就行了,先了解有这个东西
关键字;异常相关的关键字 try catch throw noexcept
1、exception 异常 运行时错误
2、异常处理的用法
使用方法 try检测,catch捕获,throw抛出异常
C++异常机制与C语言代码处理异常的优势
3、异常与函数相关的基础知识
在一个函数中throw抛出一个异常后,如果没有catch匹配捕获到对应的异常,则会一层层向外传递,直到被catch为止
4、用于函数抛出异常的throw列表
1)void func() throw(A,B,C);
2)void fun() throw();
3)void fun() throw(…);
4)void fun();
5、noexcept关键字
与函数抛出throw()作用是一致的都是用于表示函数不会抛出任何异常,是安全的,由C++11引入
6、标准库中的exception类
关键字;const以及相关的关键字mutable,constexpr
1、首先介绍C语言中的const关键字的三种用法
1)const修饰变量
2)const修饰数组
3)const修饰指针
2、C++语言中向前兼容c的那3钟用法并且新增了两种用法
1)const类型的引用
常用于函数传参来限定函数内部不对实参进行修改,同时也有告知的意思。告诉调用类库的人,实现者以及编译器
2)const修饰成员函数;常函数
用于明确告知func函数不会修改这个类的任何一个成员变量的值,注意实现的地方也要加const。
3、介绍几个与const相关的关键字,mutable,constexpr
1)mutable打洞
用来突破const成员函数中不可修改成员变量,实现单点突破,打洞的思想,从而允许const方法中可以直接修改修饰对应的成员变量
2)constexpr关键字,C++11引入的
可以 在编译时求 得 函数 或变量的 值、利用编译时候的运算能力提高运行时的效率
3)C++20新引入的2个constinit、consteval
关键字;static和this
1、在C中的使用
1)在c中static修饰静态全局变量和函数, 作用就是限制链接属性保证只有当前文件有效、C++中向下支持这种做法,但是更推荐使用namespace命名空间的机制。
2)c中static修改局部变量
改地址域到全局区,更改生命周期到整个文件,但是作用域还是在局部范围内。c++中继续沿用。
2、C++对static扩展新用法
1、静态方法
静态的属于类class而不是对象的,直接通过类名来调用,静态成员类似于静态的全局变量,但是将作用域限定到了类作用域中。
2、this关键字
作用就是让我们在未定义对象前可以在方法中调用对象里的成员 this->a这样既可
关键字;struct和class面向对象
1、struct
主要功能是对功能相关数据的封装打包,强调的是数据
2、C++中struct和class的区别
C++中struct就是class的初级阶段,class在struct基础上做了很多扩展,便有了面向对象,可以说class可以做的c++中的struct都可以做,只是有一部分特性不一样。
3、c++对象的创建和销毁
强调new和delete
关键字;auto、decltype自动类型推导
1、auto
可以根据初始化右值来自动推导类型,类型占位作用等到运行时再确定。
2、decltype
decltype(已知类型或者已知类型的变量) j;
3、两者的区别
1)auto忽略顶层const,而decltype则保留const
2)auto作为类型占用符,而decltype用法类似于sizeof运算符
3)对引用操作,auto推断出原有类型,decltype推断出引用
4)对解引用操作,auto推断出原有类型,decltype推断出引用
5)auto推断时会实际执行,decltype不会执行,只做分析。
关键字;cast 类型转换reinterpret_cast、const_cast 、static_cast 、dynamic_cast
1、C和C++在类型转换的区别
c语言中关于类型转换只有两种;一个是隐式类型转换、一个强制类型转换
c++就提供了多种,就是让程序员自己定义转换类型让编译器配合更好的达到类型检查的目的,保证程序的正确性。
2、static_cast 静态类型转换 进行基本转换
效果与隐式类型转换相同,只是作为程序员明确告知编译器我需要这样转换,你不用报警告,但是不能阻碍报错
3、reinterpret_cast 转换 通过重新解释底层位模式在类型间转换。
要编译器放弃严苛的类型检查,直接强转,从内存的解析方式出发读取强转
4、const_cast 用来修改const或者volatile属性的转换 ,也是在编译时起作用的。
5、dynamic_cast 动态转换是在运行的时候才进行转换的
编译器运行时有一套机制,用来判断是否能转,如果能转则返回转换后的对象反之失败返回NULL,因此在dynamic_cast使用的时候要先判断NULL是否转成功。
6、四种cast总结
关键字;typeid 返回数据类型的运算符
1、作用
typeid 用来返回一个变量(或对象的)类型,由于c++是强类型语言并且有严格的数据类型检查机制,则typeid可以很好的先判断出数据类型,保证程序的正确性
2、用途
typeid的主要用途实践还是在多态并结合指针引用才能发挥作用;
关键字;nullptr 空指针
1、为什么C++要引入nullptr这个关键字
与NULL的区别、以及NULL的歧义导致出错而引入nullptr
2、nullptr作用
3、nullptr的本质;C++11引入的
关键字;inline 内联函数
1、传统的内联函数与宏的区别
2、inline 的注意事项
3、C++中inline新增的特性
关键字;union 共用体
1、union 共用体、联合体
基本用法与c一致,结构体多选一的关系
2、测试大小端
3、C++11中的union扩展;编译时需要加入 -std = c++11
4、匿名共用体
一般用在内置class中作为只允许类成员访问的一个共用体变量。
关键字;内存对齐相关alignof、alignas
1、C语言内存对齐相关有两种
#pragma pack(n)直到#pragma pack()
__attribute__方法设置对齐,作用域指定类型,而不是一个范围,他还带了两个属性packed属性表示请凑对齐按1一个字节对齐、aligned()指定只对齐
2、C++引入alignof、alignas
C++11中引入了两个关键字alignof测试类型以什么对齐方式,alignas 类似于__attribute__也是用域指定类型
关键字;剩余一些关键字
1、线程相关
2、mport和module (C++20)
3、协程相关
等等
C++学习-6 如何很多全面学习C++面向对象特性;博客大致内容介绍
一;如何学习面向对象以及如何实现面向对象,面向对象要考虑什么问题
1、如何学习面向对象
具体的学习方法就是先理念;再不同面向对象的语言特性,最后就是学习实战案例
2、面向对象的编程步骤
需要注意的是一般面向对象的实现都是两部分人一个是类库的设计实现者,还有一部分是类库的调用者,学习面向可以需要有这种思维是分工合作的,很多特性都是为了保证这两部分的协作而引入的一些特性。
3、原生支持面向对象和非原生支持面向对象
都能实现面向对象,只是原生的方便简单,而非原生的需要自己去实现一遍面向对象的细节。
4、面向对象思想总结
5、典型C++面向对象编程
分成两部分;类的实现者(类的hpp和cpp),类的调用者,调用类库实现功能解决问题的
二;C++的面向对象之封装特性
1、C++的对象相关的语言特性-构造和析构
对象相关的C++的构造和析构
1)概念;
2)为什么需要引入构造和析构函数
3)析构函数被调用的两种情况以及如何申请释放动态内存
4)介绍一个Valgrind查看内存泄露的工具
5)构造函数的语法细节
(1)C++编译器会提供默认空的构造函数
(2)C++成员初始化列表
(3)构造函数使用参数默认值
6)拷贝构造函数的引入以及其引发的深浅拷贝问题
(1)为什么要引入拷贝构造函数
(2)拷贝构造函数的语法细节
(3)深浅拷贝
2、C++的访问权限相关的语言特性
访问权限的概念
1、为什么要设计访问权限,而c里面没有这个
1)保护资源;
2)隐藏外部无需知道的细节
3)体现的封装特性
2、通过访问权限带来的编程理念
“全关闭,再按需获取
3、const常方法和mutable打洞原则
1)先通过一个报错引出常方法用在面向对象的哪里
2)mutable打洞破坏const常方法的完全绝对不改变任何一个属性
3)class的前置声明
三;C++继承和多态相关的语言特性
1、继承
1)、继承的特性,本质
继承是让子类一瞬间拥有父类所有属性方法的语法糖
2)、继承中的访问权限管理
(1)三个访问权限实际是四个级别
有一个比private还有严格的等级
(2)这四个级别分别在什么时候出现
(3)如何设计访问权限
3)继承体系下子类和父类的关系
子类父类是两个独立的类
4)隐藏覆盖和类型兼容裁剪机制
父子类同名成员函数问题(隐藏覆盖机制)
类型兼容的裁剪机制
5)父类子类构造析构的关系
(1)子类不继承父类的构造析构函数
(2)为什么子类构造析构的时候会调用父类的构造析构
(3)子类到底是怎么实现的
6)继承的优势与不良继承
代码复用及构建层次框架
7)组合和继承;都是代码复用的方式
优先组合再继承
8)多继承和二义性以及虚继承解决二义性问题
(1)多继承语法
(2)多继承如何引发二义性
(3)C++专门引入虚继承virtual的语言特性来解决二义性问题
转载用内存结构解释虚继承
2、多态和虚函数
1)、多态的引入
对比隐藏和多态、以及多态需求根据对象来调用成员而不是引用
2)、多态的特征及关键实现
四;C++其他一些辅助的语言特性
1、、纯虚函数
2、虚析构函数
3、using重新定义继承访问权限问题
五;运算符重载
1、重载
函数重载和运算符重载都是语法糖
2、运算符重载的本质
执行相应的成员函数,用operator运算符为函数名
3、理解运算符各种细节
1)运算符重载总的规则:运算符左边的是this,右边的是other,运算符加操作数的整个表达式的返回值就是返回值
2)特殊的运算符重载--------赋值运算符重载
默认提供、
与拷贝构造调用时的区别、
避免赋值运算符中的自赋值、
赋值运算符重载函数返回引用,少了一次调对象赋值、
赋值运算符中涉及动态内存时的深浅拷贝问题
++和–运算符的前置后置如何实现
实现运算符重载的两种方法
六;静态类
1、static关键字的三种用法
2、静态方法,静态类概念及相关属性
从本质理解一些规则
为什么静态成员不能在构造函数,初始化成员列表初始化
为什么静态成员需要在外部进行初始化
解析静态成员的本质;限定作用域为类作用域的全局变量,他就是通过全局变量来实现的只是将其划分绑定到具体的类中
3、静态成员的用途
静态数据成员的用途之一是统计有多少个对象实际存在
静态成员与面向对象
4、静态类
七;友元函数和友元类
1、友元函数的引入
需要有外部函数要访问该类的私有属性的时候
2、使用方法
3、友元函数的两种实现
一种为外部函数,一种为其他类的成员函数。
4、友元类
友元类其实就是批量制造友元函数的一种方法,将该类中所有方法都统一全部声明为那个类的友元函数
5、为什么会有友元函数
使用友元函数的优缺点
用友元函数的两种情况
(1)运算符重载的某些场合需要使用友元
(2)两个类要共享数据的时候
友元函数和类的成员函数的区别
根本区别就是友元函数是外部的,不属于该类
共有友元函数
1个函数同时成为2个类的友元函数
七;一些剩余特性
1、嵌套类
嵌套类主要是限定了内部类的作用域
2、局部类
定义在函数内部的类,叫做局部类,只在定义他的作用域内可见,也是一种类型隐藏技术
3、总结
4、数值与对象互转
数值与对象概念
C++中数值与对象互转
(1)数值转对象,实际是调用形参类型相匹配的构造函数来实现
对象转数值,不能默认转,必须调用对象的相应转换函数来实现。
(2)对象数组
注意如果是用new来分配的对象数组,则销毁时要用delete[] xx;
八;总结
主要进行总结归纳如
C++中哪些语言特性涉及"打洞";
C++中哪些语言特性是语法糖,只是编译器为辅助开发增加的语法;
C++中哪些语言特性是保证类设计实现者和类库调用者的协作能力的;
大致总结一些这些C++特性引入的需求;
目前正在总结模板泛型相关的
2、C++项目源码介绍
1)C++解析json格式文本移植第三方库jsoncpp[缺源码解析]
2)C++船长免费课程 Google测试框架实现
一、预备知识
1、cout的本质
实现cout左移运算符通过友员函数方式重载输出直接输出对象
2、四种编程方式实现加法 面向过程 面向对象 泛型编程 函数式编程
3、编译、链接的相关问题
编译报错和链接报错
定义作用到链接阶段 声明作用到编译阶段
二、Google框架下载测试
1、预备知识
静态库.a的使用
cmake,makefile的相关知识
这里讲解国cmake相关
头文件用于编译时期,静态链接库用于链接时期
-I -大写i 指定include包含路径
-L - 大写l 指定库的路径
-l - 大写l 指定链接哪个库
2、printf显示颜色设置
性代码的方式设置;以\033开头 以m结尾,属性代码放中间 用;分隔
注意其有一个思想;在使用前归零 使用完后归零,保证前后不干扰
3、预处理的相关预备知识
预处理命令的意义就是让编译器帮我们写代码,都是在编译之前的处理
内置宏 就是我们无法实现的,需要编译器内置我们使用
变参函数 可以传递任易个参数 变参列表
##两个内容连接在一起,变参列表可以为空
\ 连接符 宏的定义只占用一行代码
条件式编译主要是用于代码剪裁
用编译命令中使用 -D定义宏 这个方法更好 不用修改源代码
4、真正实现自己的测试框架
最后的效果为;用TEST方式定义一系列测试样例,里面用EXPECT_xx实现具体测试操作,并且最后调用RUN_ALL_TESTS();执行哪里测试样例
1)实现的EXPECT_一系列函数
作用就是没有错误的时候就正常运行,有错误的时候就显示出具体的错误信息,目前采用宏的方法来实现、注意用宏的时候可以提取相同部分简化代码
2)相关颜色的封装、还是用宏封装
3)__attribute__关键字和constructor函数属性
函数属性的设置 attribute((constructor))const主程序不一定是程序的入口,constructor这个属性并先于主函数实现
4)开始实现测试框架核心代码
实现如何在RUN_ALL_TESTS方法中挨个执行测试样例的宏函数。需要设置为constructor并且将函数地址存放起来,执行RUN_ALL_TESTS按个调用即可