Qt学习路线
树图思维导图提供 Qt学习路线 在线思维导图免费制作,点击“编辑”按钮,可对 Qt学习路线 进行在线思维导图编辑,本思维导图属于思维导图模板主题,文件编号是:44c82bb972f3e6a2f87e053d02e1ae30
Qt学习路线思维导图模板大纲
1 基础知识点
程序员的第一个程序
#include<iostream> using namespace std; int main() { cout << "hello world~" << endl; //输出 system("pause"); // 暂停 return 0; }
注释
功能
让其他人能看懂代码
符号
//
单行注释
c++ 标准注释
/* code */
多行注释
C语言特有
问题
注释结尾不确定
利用预处理实现多行注释
#if 0 #endif
主函数
应用程序入口,操作系统调用程序的接口
main
一个项目只能有一个main函数
单个文件只能出现一个
多个文件只能一个文件中有一个
常见的五种
int main() { return 0; }
c++标准主函数形式
int main(void) { return 0; }
C语言标准主函数形式
void 表示不接受任何参数
无void 表示参数类型和数量不确定
int main(int argc, char* argv[]) { return 0; }
c/c++标准主函数形式,使用命令行参数
main() { }
老标准支持的写法,现在的 C语言还支持这种写法
但是尽量不要这么写
c++不支持这种写法
void main() { }
不提倡
c++之父说,这种形式的主函数,在C语言和c++中,都没有被定义
书上说,这种主函数写法逻辑上符合,而且有很多系统支持,但是考虑到代码的移植性,建议用标准型式。标准形式所有系统都支持。
头文件
#include<iostream.h>
老版头文件,继承C语言的头文件习惯,vc6.0可用,vs正常情况下不可以用
#include<iostream> using namespace std;
标准头文件,vc,vs均可用
命名空间
功能:区分同名变量或者函数
创建
namespace name { code; };
名字不能重复
3种使用方法
打开 using namespace name;
name::变量名/函数
:: 作用域运算符
using name::成员;
指定开放某个特定成员
输入输出
c++:
cout
是个对象,不是关键字,也不是函数
输出
常量
cout << "hello C3~" ;
cout << ' ' ;
cout << 12.12;
变量
char c = 'a'; int a = 1; double b = 2.1; char *p = "hello C3~"; cout << c << ' ' << a << ' ' << b << ' ' << p;
可以输出一个,也可以连续输出,怎么样好看怎样写
这个比printf智能(需要指定类型输出%c,%d,%s...),cout可以自动识别变量类型
输出控制
控制符
endl
屏幕光标移动到下一行开头
重起一行,刷新缓冲区
换行符
\n
重起一行
异同
同
重起一行显示,屏幕光标移动到下一行开头
异
endl,多了一个刷新缓冲区的操作,这个操作,会使缓冲的字符立刻显示到屏幕上。 \n,则不保证这一点,也就是说,在一些系统上,\n的显示会慢半拍。常用的这些系统,都不会这样,也就是说,显示这个功能,基本没有区别。
endl的效率,是慢的。多了操作
cin
是个对象,不是关键字,也不是函数
输入
变量
char c = 'a'; int a = 1; double b = 2.1; char *p = "hello C3~"; cin >> c >> a >> b ; cout << c << ' ' << a << ' ' << b << ' ' << p;
可以输入一个,也可以连续输入,怎么样好看怎样写
这个比scanf智能(需要指定类型输出%c,%d,%s...),cin可以自动识别变量类型
c: scanf printf
数据类型
基本数据类型
字符型
char
内存大小
表示范围范围
数值类型
整形
short
int
long
long long
浮点型
float
double
long double
构造类型
数组
[ ]的三种作用
声明变量的时候有[ ],表示声明的是数组变量
函数参数有[ ],此时表示指针
地址+[ ],表示下标运算
一维数组
字符数组/字符串
定义
以'\0'结尾的字符数组
输出输入
c++:cout << name; cin >> name;
C: printf("%s",name); scanf("%s",name);
字符串的声明方式(四种形式)
操作
库函数
strcmp(),strlen(),strcpy,strcat()...等等
其他类型的数组
注意区分初始化和赋值的区别
遍历
注意越界问题
地址
取地址运算符:&
a == &a[0]
首元素的首地址
&a[0], &a[1].....
单个元素地址
&a
数组的地址
二维数组
声明和初始化
地址
&a[1], &a[2], &a[0] == a
一维数组元素地址
&a[0][1], &a[1][0] == a[1]....&a[0][0] == a[0] ;
取元素地址
&a
二维数组的地址
结构体
struct
结构体类型声明方法
有名字,无名字
结构体变量的声明方法
初始化
成员赋值
成员调用方法
取成员运算符
.
->
结构体大小
内存对齐
链表
单向链表
双向链表
c++独有
声明变量可以不用struct关键字
可以放函数成员
C语言的不可以放函数成员,但是可以放函数地址、
是一个特殊的类
联合/共同体
union
特点
所有成员共享内存
大小
最大的成员的大小
一般初始化最大的成员
延伸
大小端模式
大小端模式的测试方法
枚举
enum
声明以及使用
使用有意义的字符串
大小
4字节
实为int类型的数的集合
指针
内存申请与释放
C++
new
申请单个空间
int *p = new int; int *p = new int(10); 初始化一个值
类型一定要匹配上
struct Node{code;}; Node *p = new Node;
其他类型同理
申请数组空间
int *p = new int[10];
memset(起始地址,字节数,设置的值),设置内存初始值
堆区的空间不像是栈区的那种,可以在声明的时候初始化。
其他类型同理
失败返回一个NULL,同C语言的malloc一样
delete
delete p; <==> new type;
对于标准来说,不匹配释放,结果是不确定的。
delete [ ] p;<==> new type [count];
一定要加上,
delete NULL 是安全的, free(NULL)会崩溃的
C: malloc() free()
区别
new delete 可以触发构造和析构
同时释放一块空间大于1次,是不行的
指针声明和空间分配方式不同,使用完全相同,所以说,在c++里,除了对象空间申请之外,用malloc 和 free是完全可以的,
指针类型
基本数据类型的指针
数组指针 与 指针数组
一维数组
二维数组
二级指针
函数指针
结构体指针
指针的大小
地址+1 是加了一个类型的大小
64bit编译器
8字节
32bit编译器
4字节
*的三种作用(c/c++)
声明的时候有*,表示指针变量
*+地址,表示地址操作符,取内容
数字*数字,表示乘法
引用变量
概念
引用是已定义的变量的别名(另一个名称),两者用法完全一样了
同类理解
typedef 是给类型起别名
声明与定义
基本数据类型变量的引用
int b = 12; int &c = b; int &d = b; int &e = d;
定义的时候就要初始化
不能指向其他的了
看地址
其他类型同理
常量的引用
const int &n = 12; const char &c = 'a'; const float &f = 123.123f;
复合数据类型的引用
数组的引用
int a[2]; int (&b)[2] = a; int a[2][3]; int (&c)[2][3] = a;
方式同数组指针一样
结构体的引用
类型 & 名字 = 结构体实例;
指针的引用
int* p = NULL; int* (&d) = p;
引用与函数
做函数参数
最主要的功能
修改参数的值
void Change(int& a) { a = 12; }
void Change(int a) { a = 12; }
void Change(int* a) { *a = 12; }
交换两个数的值
void ExChange(int& a, int& b) { int ntemp = a; a = b; b = nTemp; }
引用与返回值
不要引用局部变量就行
注意:操作非法内存的结果是未知的
引用与指针的区别
1、引用声明就要初始化,指针不用 int *p = NULL;
2、引用不能指向其他变量了,指针则可以任意指向。p = &a; p = &d;
3、引用不占存储空间,指针占空间
4、引用效率更高,指针式间接操作
5、引用更安全,指针可以偏移
6、指针更灵活,直接操作地址,指针更通用c语言和c++都行
&的三种作用
声明变量的时候有&,表示引用
变量前边+&,表示取地址
数&数,表示位与运算
运算符
优先级
结合性
运算符优先级表
这个表格不用记,写代码的时候直接加括号
流程结构
顺序
由上向下一步一步执行
循环
可控循环的三要素
循环控制变量有初始值
循环执行条件
真 == 1;
假 == 0;
初始值的变化
三种结构
入口条件循环
for(初始值;条件;变化)
for循环结构执行次序
while(条件)
退出条件循环
do{} while()
至少执行一次,循环体内部语句
continue
结束本次循环,继续下一次循环
break
跳出所在循环
c++增强的for循环
变量定义的位置
vc和vs结构内定义循环控制变量的作用域区别
分支跳转/选择
if (条件){} else if(条件){} else{}
switch(ID) { case ID: break;}
goto
可以根据逻辑,写成循环结构或者跳转结构
建议不用
函数
声明,定义
函数类型
无参数,无返回值
C:标准C语言,函数没参数需要写个void
c++:不用写void
无参数,有返回值
return ;
返回局部变量
有参数,有/无返回值
传值与传址
参数缺省值/默认值
形式
int fun(int a = 0, char c = 'b', float f = 12.12 );
全部指定
int fun(int a , char c = 'b', float f = 12.12 );
部分指定
一定是从右向左,逐个指定
int fun(int a = 12, char c , float f = 12.12 );
随意指定是会报错的
使用
有默认值得参数,传递实参会覆盖默认值,不传递实参会使用默认值,极大的增加了函数调用的灵活性
注意
使用函数原型
函数声明时候写默认
函数定义处不要写
不使用函数原型
直接写就行了
函数指针
函数重载
定义
同一作用域内
相对的一个位置,大家理解即可
函数名字相同
参数列表不同
参数类型不同
这两个条件是 或 的关系
参数个数不同
形式
void fun(int a); void fun(int a, int b); void fun(char c); void fun(float f, double d);
调用
系统会根据参数的形式,自动找到要调用的函数
例子
int main() { fun(1); fun('a'); fun(2,3); fun(12.13f, 123.123); }
何时使用,或者有什么好处
函数调用更灵活了
注意
默认参数和重载结合使用,可能会造成调用不明确
例子
void fun1(int a, int b, int c = 0); void fun1(int a, int b); int main() { fun(1,2); //传递两个参数,编译正常,运行时候就会报错 }
返回值不作为函数重载的条件
int fun(); void fun(); //这种声明方式报 重定义 错误
参数是浮点型float,double的护卫重载的函数,一定要注意参数传递
递归函数
展开再理解
文件操作
文件操作流程
打开文件
fopen
文件的打开方式
文本模式
二进制模式
操作文件
fread(),fwrite(),fgets().....
关闭文件
fclose()
文件写入磁盘的钥匙
内存管理
位运算
进制转换
二进制与16进制,十进制与16进制, 十进制与2进制
位运算符
&,|,~,^
区别于逻辑运算符
内存分区
变量的作用域
堆区,栈区,全局区,静态/全局常量区,代码区
1 内存分配未成功,你却使用
malloc
2 内存虽然分配成功,但是没有初始化你就引用他
3 内存分配成功,并且初始化成功,但是操作的时候超过内存边界
4 内存泄露
5 内存释放了,你却继续使用
6 内存碎片
7 内存
类型转换
隐是类型转换
显示类型转换
强制类型转换
2 类(封装、继承、多态)
类和对象
类和面向对象的关系
面向对象是一种编程思想
类是一个语法
意义:面向对象的编程思想,要以这个语法(类)来实现。 大家暂时不要强行理解面向对象这种思想,因为这个理解是要基于很多项目经验的,不是一朝一夕就能领悟的。 学好类,就行了
类
定义:具有相同属性和行为的对象的集合(人类,就是一个人的集合,胖胖秦就是这个类的一个具体个体,或者叫对象)
类实例
class CPeople { public: int age; void Test() { age = 12; cout << age << endl; } }; int main() { CPeople op; op.Test(); CPeople* op1 = new CPeople; op1->Test(); delete op1; return 0; }
类声明
class 类名 { };
跟结构体基本是一样的,只不过关键字是class
结构体是类的一个特定情况
声明对象
CPeople op;
CPeople* op1 = new CPeople;
成员调用
栈区普通对象
对象.成员
op.Test();
堆区指针对象
对象->成员
op1->Test();
delete op1;
类的所有成员(个别特殊static),必须通过对象访问
访问修饰符
关键字
private
类内可见
类内不写访问修饰符,默认是private
protected
类内以及子类可见
public
类外可见
c++的结构体,默认是public
友元
关键字
friend
友元函数
friend void fun();
需要声明
friend int main();
不需要声明
友元类
使用protected成员有两种方法
继承
友元
使用private成员
友元
特点
不受访问修饰符影响
可以有多个友元
缺点:破坏了类的封装性,不是迫不得已,不要用
接口,
作用范围
书写位置开始,一直到下个修饰符,或者类结尾的花括号 }
拓展功能
作为类内成员分类的工具,这个,修饰符,写多少都行
安全性
函数成员
构造函数
产生
普通数据成员不能够在类内直接赋值,因为只有对象创建的时候才分配空间 那么,我们的数据如何赋予初始值呢。我们可以定义一个成员函数,对成员统一赋值
void init(int b) { a = a; }
形式
类名(参数列表){}
无返回值
作用
对数据成员赋初始值
调用
对象定义的时候
栈区对象
堆区对象
声明指针并不会调用构造函数,new空间的时候调用
类型
默认构造函数
什么都不做,即空的
只要宏观声明的构造函数,默认的就没有了
无参数
有参数构造函数
通过对象传递
可以指定默认值
多个构造函数构成重载
成员函数定义
类内定义
类外
类内声明
意义是用于多文件
类外定义
初始化列表
初始化与赋值的区别
意义上
初始化是一个变量或者对象产生之时就赋予一个初始值,伴随性质
赋值是一个变量或者对象产生之后的任意时刻可以赋予一个值,随意性质
宏观代码上
基本数据类型
作用相同
数组,结构体
初始化,和赋值的形式不同
作用相同
引用,const
只能初始化
不能赋值
函数定义和声明
形式
构造函数之后加个冒号:a(1),b(2)
不是花括号之后
作用
跟构造函数的区别
基本数据类型,用哪个都行
引用,const必须用初始化列表
对数据成员进行初始化
可通过数值对数据成员初始化
可通过构造函数参数对数据成员进行初始化
可通过成员之间相互初始化
成员初始化的顺序
初始化的方式很多,大家根据自己的需要用
执行顺序
在构造函数之前
引用和const
引用
引用成员
引用参数
引用类外
const
参数
常量
注意点
多个构造函数,初始化列表绑定所在的构造函数
数组和结构体如何使用初始化列表
数组
CStu() : arr()
vc无效果
vs有效果
通常设置设置数组元素全为0的方法
memset
for循环
结构体
可直接赋值
用初始化列表反而增加了复杂性
析构函数
作用
清理工作
比如我们用new给成员申请了空间,析构函数内可以释放掉
调用时间决定了他的主要作用
形式
~类名()
只有一个,没有参数
没有重载
默认析构函数
什么都不做,类比默认构造函数
调用
对象声明周期结束时,自动调用
局部对象
临时对象
作用域
所在语句
指针对象
delete
默认
malloc 和 new的区别
new会触发构造函数,malloc不会
free 和delete区别
delete会触发析构函数,free不会
常函数
形式
void fun() const {;}
构造和析构 不可以是常函数
特点
可以使用数据成员,不能修改数据成员
对函数的功能有更明确的限定
常函数的this指针是 const CStu*
常对象只能调用常函数,不能调用普通函数
static
形式
static int a;
static void fun(){}
使用方式
对象调用
类名作用域
静态成员
类外初始化
无static
静态常量整型数据成员可以直接进行初始化
static const float a = 13.12f;
不行
static const int a = 13.12f;
整形
不使用循环,来个自加1
静态成员函数
无this
不能调用成员成员,可以调用静态成员
可以作为一种指挥该类所有对象的作用
他是属于类的属性,不是对象,即所有对象共有一个
可以通过类名调用
可以通过对象调用
拷贝构造/复制构造:copy
形式
CStu(const CStu&)
本质即构造函数
参数是本类的常引用
何时调用
1、新建一个对象,并将其初始化为同类现有对象
CStu a;
声明一个对象
1、CStu a1(a);
2、CStu a2 = a;
3、CStu a3 = CStu(a);
4、CStu* a4 = new CStu(a);
赋值不会的
CStu s; CStu p; s = p;
2、当程序生成对象副本时
函数参数传递对象的值
函数返回对象
有何功能
默认的复制构造函数,逐个复制非静态成员(成员的复制成为浅复制)值,复制的是成员的值
系统默认的这个又叫浅拷贝
实践一下,模仿一下默认的
模仿的这个也是浅拷贝
同一个类的多个对象,内存排布是一样的,地址不同
演示问题
指针成员
构造分配空间
析构释放空间
深拷贝
指针成员不能直接赋值,要用内存拷贝,memcpy,strcpyd等
解决拷贝构造所引发的,指针成员二次释放崩溃的问题的方式
深拷贝
传地址
传引用
内联函数
常规函数调用过程
调用时,根据函数地址
跳到函数代码空间,执行指令
执行完,再跳转到调用的位置
综合:来回跳跃+记录跳跃的位置==一定的系统开销(资源+时间)
内联函数
inline
函数声明要加inline
函数定义要加inline
注意:只写声明位置不管事儿
作用
用相应的代码替换调用
比常规函数稍快
代价是占用更多内存
常规函数和内联函数如何选择
特点
时间和空间
1看实际需要
空间换时间
时间换空间
2看性价比
实际
函数代码少,流程直接,调用频繁
循环里的
编译器智能
程序猿请求将函数作为内联函数时,编译器不一定会答应,
函数体过大
递归不能是内联函数
效果:写了等于没写,按常规函数进行编译
这个特性是编译器特性,即不是所有编译器都实现了这一功能
内联函数比宏功能更强
测试一个参数宏
测试参数内联函数
类与内联函数
类内定义都是内联函数
显示定义
隐式定义
定义在外
有inline 是内联
没有inline不是内联
内联函数与多文件
内联函数可以有多个定义,多个定义必须完全一致
所以通常,内联函数写在头文件里
数据成员
相对特殊
引用成员
初始化列表初始化
const成员
初始化列表初始化
静态成员
类外初始化
无this指针
静态常量成员
可在类内直接初始化
也可在类外初始化
指针成员
注意拷贝构造产生的问题
常规
其他类型
this
作用
区分同名的
是指向当前对象的指针
所以我们可以通过指针,访问成员
对象创建的时候才有的
类型
对应对象的类的指针类型
this指针不是成员
this作用域是在类内部,系统默认传递给函数(非静态函数)的隐含参数
继承
继承小实例
class CPeople { public: int hands; int head; void speak(){ } void study(){ } }; class CXiaoming : public CPeople { public: int age; char *name; void speakChinese(){ } void work() { } } class CXiaohua : public CPeople { public: int age; char *name; void alllanguage(){ } } int main() { CXiaoming xiaming; xiaoming.hands;..... CXiaohua xiaohua; xiaohua.hands;...... return 0; }
继承的作用
代码的重用性
继承的格式
class CXiaoming : public CPeople
基类或者叫父类
派生类或者叫子类
可以继承很多层
原理都一样
继承对象的声明以及成员调用调用
普通对象
指针对象
基类也可以自己创建对象
继承的限定词
private
父类中public,protected,在子类中为private,降低访问权限
protected
父类的public成员,子类中为protected,即为降低权限
public
父类如何子类如何
成员的继承
函数成员
构造函数
以无参构造演示,子类和父类构造函数的执行顺序
先调用父类的,父类还有父类就继续向上
父类有参数的构造,需要通过子类初始化列表来传递参数
只关注自己父亲的
多个构造函数选择传递
默认是无参的
参数列表写谁,调用谁
析构函数
调用顺序
由辈分小的到辈分大的
覆盖
父类和子类中出现同名的成员时,C++采用的一种处理方式,就叫覆盖
数据成员同名
类内 ,子类覆盖父类,可以用类名作用域区分
类外: 类名作用域区分
父类子类函数名字相同
子类覆盖父类
使用时可以通过类名作用域区分
父类子类的函数没有重载关系
友元不能被继承
继承
静态只有一份儿
虚继承
多继承
多个基类
子类的子类
虚拟继承是多重继承中特有的概念。虚拟基类是为解决多重继承而出现的
父类叫做虚基类
解决多继承中访问不明确的问题
不建议用,结构复杂,内存开销比较大
多态与虚函数
多态与虚函数
多态是一种泛型编程思想
即同样的代码,实现不同的功能
父类的指针,调用子类的函数
虚函数是实现这个思想的语法基础
父类指针指向子类空间
CFather* p = new CSon;
但是不能调用子类的函数
形式
virtual void fun() ;
子类的函数 要和这个函数一样
多个子类,换子类就调用子类的
多态针对于指针对象
多态
即父类的一个指针,可以有多种执行状态,即多态
逻辑
问问题
快速检索到面试官想问什么?
多态
子类重写父类的虚函数
内涵和外延
多态是什么?为什么要用多态?怎么样使用多态
内涵
虚函数表 虚函数指针 内存分布 多态的逆向表现 多态汇编
外延
特点
重写
父类和子类相同,父类是虚函数。叫做重写
虚 针对于 函数成员
子类重写的函数,默认是虚函数,可以显示加virtual,也可以不加
名字参数相同
返回值类型相同
重写
返回值类型不同(只能是当前所在类)
协变
不是内联函数
构造函数不能是虚函数
虚表
虚函数覆盖原理
1、根据父类的指针,找到父类的函数
2、看父类的这个show是不是虚函数
是
进入到虚表,执行表中这个(自己/重写)
不是
执行自己
CFather* p = new CSon; p->show();
取虚表地址,以及内容
对象空间的最开始四字节内容,就是虚表(虚函数列表)的地址,叫虚指针
(int*)*(int*)p+0 (int*)*(int*)p+1 (int*)*(int*)p+2
取到的是函数地址,想要调用,要转换成对应类型的函数指针
void (*p)(int a) = (void (*)(int))(*((int*)*(int*)p+1))
虚析构
delete哪个类型的指针,就调用谁的析构函数
多态中,如果释放父类指针,只会调用父类的析构函数,所以加了虚析构,就会子类父类都调用了
纯虚函数
纯虚函数
形式
virtual void fun() = 0;
特点
可以没有函数实现
继承这个基类的子类必须实现它,才能定义对象
抽象类
有纯虚函数的就是抽象类
接口类
全是纯虚函数的,叫接口类
可以有构造函数,和成员什么的
3 模板
函数模板
首先通过函数重载,实现同名函数,根据不同的参数类型,进行智能调用
引出函数模板
对比函数重载,函数模板,只需要一个函数就搞定
意义:模板是泛型编程的一种重要思想。stl就是利用模板实现的一个具体实例
模板的写法
template <typename T> void fun(T tt) { cout << tt << endl; }
格式
书写
template <typename T>
template <class T>
可以有多个参数
template <typename T, typename Y>
作用域
仅对下边挨着的代码段有效
具体化
就是将我们的指定的类型,单独处理
template<> void fun<job>(job& j1, job& j2);
要单独写个实现
调用:fun(结构1, 结构2);
调用顺序
原版函数->具体化->模板
实例化
生成指定类型的函数定义
template void fun<job>(job& j1, job& j2);
调用:fun(结构1, 结构2);
没有函数实现
类模板
可以设定默认值
template <typename T, typename Y = char>
只有类模板可以有默认值
必须从右向左连续赋值默认类型,跟函数参数默认值一样
传递的时候会覆盖掉
创建对象传递模板参数列表
类模板,需要在类型后加模板参数列表
CFather<int, char> fp;
有默认值的时候可以不传
但是必须要有<>
CFather<> fp;
CFather<int,char>* pf = new CFather<int ,char>;
除了类之外,热河位置出现CFather 都要加上模板参数列表
类外实现的函数模板的写法
template <class T,class B , class C> void CA<T, B, C>::fun(T a) { }
void CFather<int, char>::Show() { cout << a << endl; }
继承的模板
主要是模板参数列表的传递
直接指定固定的类型
通过子类模板参数列表传递
继承的时候要写
:public CFather<T>
构造函数传递(父类有参数构造)
:CFather<T>
创建对象时候要写
CFather<int, char> fp;
多态模板
子类没模板
CFather<short, char>* pf = new CSon;
子类有模板
CFather<short, char>* pf = new CSon<short, int ,char>;
类型一定要对应上
4 常用的STL
string
vector
list和forward_list
set
map
5 C++新特性
总则:C++新特性可以用传统的C++语法实现,从另外的维度,很直接地把原来复杂的问题简单化
C++11/14/17
关键字及新语法
auto关键字
编译器根据上下文情况,确定auto变量的真正类型
auto作为函数返回值时,只能用于定义函数,不能用于声明函数
nullptr
class Test { public: void TestWork(int index) { std::cout << "TestWork 1" << std::endl; } void TestWork(int * index) { std::cout << "TestWork 2" << std::endl; } }; int main() { Test test; test.TestWork(NULL); test.TestWork(nullptr); }
使用nullptr的时候,我们能调用到正确的函数
for循环语法
int main() { int numbers[] = { 1,2,3,4,5 }; std::cout << "numbers:" << std::endl; for (auto number : numbers) { std::cout << number << std::endl; } }
不仅仅局限于数据,STL容器都同样适用
STL容器
std::array
std::array相对于数组,增加了迭代器等函数
std::forwardlist
std::forward_list为C++新增的线性表,与list区别在于它是单向链表
std::unordered_map
std::map使用的数据结构为二叉树,而std::unordered_map内部是哈希表的实现方式
std::unordered_set
std::unordered_set的数据存储结构也是哈希表的方式结构
多线程
std::thread
std::thread为C++11的线程类,使用方法和boost接口一样,非常方便,同时,C++11的std::thread解决了boost::thread中构成参数限制的问题,得益于C++11的可变参数的设计风格
std::atomic
std::atomic为C++11分装的原子数据类型
从功能上看,简单地说,原子数据类型不会发生数据竞争,能直接用在多线程中而不必我们用户对其进行添加互斥资源锁的类型。从实现上,大家可以理解为这些原子类型内部自己加了锁
std::condition_variable
C++11中的std::condition_variable就像Linux下使用pthread_cond_wait和pthread_cond_signal一样,可以让线程休眠,直到别唤醒,现在在从新执行。线程等待在多线程编程中使用非常频繁,经常需要等待一些异步执行的条件的返回结果
智能指针与内存管理
智能指针
智能指针只是用对象去管理一个资源指针,同时用一个计数器计算当前指针引用对象的个数,当管理指针的对象增加或减少时,计数器也相应加1或减1,当最后一个指针管理对象销毁时,计数器为1,此时在销毁指针管理对象的同时,也把指针管理对象所管理的指针进行delete操作
std::shared_ptr
std::shared_ptr包装了new操作符动态分别的内存,可以自由拷贝复制,基本上是使用最多的一个智能指针类型
include <memory> class Test { public: Test() { std::cout << "Test()" << std::endl; } ~Test() { std::cout << "~Test()" << std::endl; } }; int main() { std::shared_ptr<Test> p1 = std::make_shared<Test>(); std::cout << "1 ref:" << p1.use_count() << std::endl; { std::shared_ptr<Test> p2 = p1; std::cout << "2 ref:" << p1.use_count() << std::endl; } std::cout << "3 ref:" << p1.use_count() << std::endl; return 0; }
std::weak_ptr
为了解决std::shared_ptr在相互引用的情况下出现的问题而存在的
其他
std::function、std::bind封装可执行对象
std::bind和std::function也是从boost中移植进来的C++新标准,这两个语法使得封装可执行对象变得简单而易用
lamda表达式
在众多的C++11新特性中,lamda表达式不仅仅是一个语法新特性,C++11的lamda表达式在一定程度上还冲击着对传统C++编程的思维和想法
示例
int main() { auto add= [](int a, int b)->int{ return a + b; }; int ret = add(1,2); std::cout << "ret:" << ret << std::endl; return 0; }
[]:中括号用于控制main函数与内,lamda表达式之前的变量在lamda表达式中的访问形式
->int:lamda表达式函数的返回值定义
{}:大括号内为lamda表达式的函数体
运行结果
6 C++对象模型
1Qt的安装
2 Qt的开发环境
Qt Creator
Linux环境
3 VS安装Qt的插件
4 Qt的信号与槽机制
5 布局管理器
6 Qt的关键类
QString
QList
QVector
QMap
QHash
QVariant
QLabel
显示文字
显示图片
显示动画
QLineEdit
QTextEdit
QPlainTextEdit
QButton
QPushButton
QToolButton
QRadioButton
QCheckBox
QCommandLinkButton
QDialogButtonBox
QComboBox
QFontComboBox
QSpinBox
QTimeEdit,QDateEdit,QDateTimeEdit
QDial
QScrollBar
QSlider
标准对话框
消息对话框类
自定义消息框
进度条
可扩展对话框
Qt文件操作
Qt图像坐标变换
Qt排版
Qt图形与图片
Qt模型/视图结构
Qt网络与通信
Qt多线程
Qt数据库
QML
Qt Quick
OPenCV
行为型模式
创建者模式
结构型模式
程序员老秦原创,B站搜索程序员老秦
1 QT单步调试
2 QTestLib框架
3 日志
日志的设计、实现与测试
4 单元测试
最好是包含以上全部知识点的项目
加密播放器
网络天气预报
海康威视萤石云
基础面试
项目面试
树图思维导图提供 一、研究内容 在线思维导图免费制作,点击“编辑”按钮,可对 一、研究内容 进行在线思维导图编辑,本思维导图属于思维导图模板主题,文件编号是:4f21797dd3e8b08f1951dfc24e7be94f
树图思维导图提供 如何从大历史观学习中国历史 在线思维导图免费制作,点击“编辑”按钮,可对 如何从大历史观学习中国历史 进行在线思维导图编辑,本思维导图属于思维导图模板主题,文件编号是:5a22832470b2860422e8670dd763724d