c++ 版本
https://blog.csdn.net/m0_37251750/article/details/125159533
头文件
https://www.runoob.com/w3cnote/cpp-header.html
作用
类似python的包
原理
1 2 3 4
| /* math.h */ double f1(); double f2(double); /* end of math.h */
|
1 2 3 4 5 6 7 8 9 10 11 12
| /* math.cpp */ double f1() { //do something here.... return; } double f2(double a) { //do something here... return a * a; } /* end of math.cpp */
|
1 2 3 4 5 6 7 8
| /* main.cpp */ #include "math.h" main() { int number1 = f1(); int number2 = f2(number1); } /* end of main.cpp */
|
1 预编译
include 的作用就是把每一个它出现的地方,替换成它后面所写的那个文件的内容。简单的文本替换,别无其他
main.cpp首先include “math.h”,就是把math.h的东西全部替换过来
2 编译
main.cpp f1,f2的声明 变 符号表
3 链接
根据符号表就可以在math.cpp找到f1,f2的实现
怎么写头文件
.h文件中能包含:
- 类成员数据的声明,但不能赋值
- 类静态数据成员的定义和赋值,但不建议,只是个声明就好。
- 类的成员函数的声明
- 非类成员函数的声明
- 常数的定义:如:constint a=5;
- 静态函数的定义
- 类的内联函数的定义
不能包含:
- 1.所有非静态变量(不是类的数据成员)的声明
- 2.默认命名空间声明不要放在头文件,using namespace std;等应放在.cpp中,在 .h 文件中使用 std::string
怎么使用
https://blog.csdn.net/cnds123/article/details/132038160
首先要加载库文件
然后include
声明 定义
https://bbs.huaweicloud.com/blogs/292599
变量
声明:告诉编译器变量的名称和类型,而不分配内存
定义:给变量分配内存,可以为变量赋初值
函数
函数只要有实现即为定义,否则为声明
注意
声明要在使用前面 否则报错
关键字
static
1 变量
只能在定义时初始化,以后不行 如果没有显式初始化,会被程序自动初始化为0 静态成员变量必须类外初始化
生命周期和全局变量一样 程序结束才释放
就一个 公用
作用域:
静态成员变量:类内
静态全局变量:本文件
静态局部变量:函数内
2 函数
静态成员函数:和类绑定 和对象没有关系
静态函数:只能在本文件用
extern
https://www.51cto.com/article/768503.html
https://blog.csdn.net/w2865673691/article/details/13018563
https://blog.csdn.net/xingjiarong/article/details/47656339
extern
原理:就是先声明 告诉编译器定义在别的地方
作用:在本文件使用别的文件的变量和函数 和include类似
extern “c”
表示按照c语言的方式去编译
final
类名后加final
1.禁止被继承,但是可以继承别人
likely unlikely
if(likely(condition)), if(unlikely(condition)), if(condition)功能逻辑上一样
差别就是likely,unlikely编译器上有优化,likely告诉编译器大概率会走这里,unlikely告诉编译器大概率不走这
__attribute__
https://cloud.tencent.com/developer/article/1400469
override
继承的时候
子类函数声明的时候后面 + override 此时没有重写就会报错
auto
自动匹配类型
声明指针类型时,用auto和auto *没有任何区别
const
https://www.runoob.com/w3cnote/cpp-const-keyword.html
1.成员函数
不能修改非静态成员变量
2.函数返回值
3.auto const vs const auto
auto const 是一个常量
const auto 是一个变量 但是值不能改
4.不能移动赋值 移动初始化
5.成员变量
和成员变量引用类似
using
https://zhuanlan.zhihu.com/p/156155959
default
使用默认实现
只能作用于类内的某些特殊函数 比如构造 析构
thread_local
explicit
https://blog.csdn.net/fengbingchun/article/details/51168728
typedef
起别名
move
将左值转化为右值
namespace
https://www.runoob.com/cplusplus/cpp-namespaces.html
区分同名变量和函数
forward
https://zhuanlan.zhihu.com/p/161039484
引用的对象可能是左值 也可能是右值 但是引用变量是左值 引用变量加上forward就可以得到之前的状态
函数
怎么写
声明
1
| return_type function_name( parameter list );
|
函数参数
1 本质
double& setValues(int& i)
int & i = 传入的变量
2 传值 传指针 传引用
3 参数的默认值
函数声明或者函数实现有一个地方有默认值就可以
4 可变参数
函数返回值
https://blog.csdn.net/jmh1996/article/details/78384083
1 本质
int fun(int a){
return a*a;
}
int result = fun(4);
a.值给临时变量
int tmp = a*a
b.临时变量值给外面变量
int result = tmp
= 0
没有函数体
= default
默认实现
匿名函数
https://www.runoob.com/cplusplus/cpp-functions.html
内联函数
https://zhuanlan.zhihu.com/p/375828786
好处:效率
坏处:代码膨胀
析构函数
when
当变量的内存要释放的时候,会自动调用析构函数
注意引用 (左值引用 右值引用) 当最后一个标签的生命周期结束时候才会析构
作用
不是用来释放内存的 是在释放内存前用来做一些清理工作的
析构顺序
原则就是先构造后析构 刚好和构造函数的顺序反一下
先调用子类的析构函数 -> 析构子类成员变量 从下往上 -> 调用父类的析构函数 -> 析构父类成员变量 从下往上
默认的
不写 就有默认的
写了 就覆盖
虚析构
就是父类的析构函数+ virtual
1 多态
不加:只析构父类 内存泄露
加:先析构子类 然后析构父类
原理??
2 没有多态
无所谓
构造函数
when
申请内存的时候
作用
初始化
初始化列表
https://blog.csdn.net/hzhsan/article/details/55187877
构造函数有两个阶段
1.初始化
初始化列表就是显示初始化
不写初始化列表就是隐性初始化
2.赋值
函数体里面
普通构造函数
有默认的
拷贝构造
有默认的
浅拷贝 深拷贝
https://blog.csdn.net/weixin_44788542/article/details/126234533
移动构造
有默认的
参数左值引用就是拷贝 右值引用就是移动
转移所有权
https://blog.csdn.net/weixin_44788542/article/details/126284429
和赋值运算符的区别
初始化就是调用构造函数 非初始化就是调用赋值运算符
数组
数组名就是指向第一个元素的地址
数组作为函数返回值 返回指针
数组作为函数参数 传指针
指针
1 裸指针
本质
指针值就是地址 指针类型决定可以访问的内存大小
指针本身也是一种数据类型 占用内存
nullptr
调用普通函数没事
调用虚函数会core
野指针
https://zhuanlan.zhihu.com/p/337060273
指针运算
p
*p
p[0]=*p
p+1 地址值+p的类型字节数
指针数组
int *ptr[MAX];
在这里,把 ptr 声明为一个数组,由 MAX 个整数指针组成
指向指针的指针
释放指针
1 非new的系统自动释放
2 new的必须手动释放
delete p
p = nullptr 防止野指针
delete nullptr 不会报错
2 函数指针
函数名,函数名取地址,函数名取值结果一样
https://www.runoob.com/cprogramming/c-fun-pointer-callback.html
3 智能指针
本质
在普通指针外包一层
和普通指针区别 new出来的 普通指针要手动释放 智能指针会自动释放
指向数组
https://blog.csdn.net/weixin_43705457/article/details/97617676
操作
1 reset
p.reset(q) // 释放p原来指向的内存,然后重新指向q
p.reset() // 重置为nullptr,等于手动释放
2 get
p.get() // 获取指针地址
3 release
q=p.release() // 返回原来指向的地址,p变为nullptr,其实就是释放对指针的管理权
4 unique_ptr
不能拷贝
只能移动或者引用
5 shard_ptr
可以拷贝
当引用计数为0 才会释放管理的内存
4 this指针
值:new的地址值,或者是当前对象的地址值
类型:就是当前类的类型
类内的函数调用 本质是this.funcname 不写的话默认有this
5 指针管理
说白了就是new出来的指针 谁来delete
不要忘记delete 不要重复delete
引用
https://www.cnblogs.com/david-china/p/17080072.html
左值 右值
区分左值还是右值 取决于 能否取地址
左值引用
&
引用左值
本质就是贴标签
省时 省内存
引用右值
加const
延长了右值的生命周期
贴标签
哪些要引用哪些不要
原则是大的要 小的不要 比如说
要:字符串 对象
不要:指针 数字
函数返回值
当返回一个引用时,要注意被引用的对象不能超出作用域
https://mesywang.github.io/2019/09/10/C++%E4%B8%AD%E5%BC%95%E7%94%A8%E4%BD%9C%E4%B8%BA%E5%87%BD%E6%95%B0%E7%9A%84%E8%BF%94%E5%9B%9E%E5%80%BC/
成员变量是引用
https://blog.csdn.net/lazyq7/article/details/48186291
右值引用
&&
引用右值
延长了右值的生命周期
贴标签
引用左值
move(左值) -> 右值
贴标签
万能引用
https://theonegis.github.io/cxx/C-%E4%B8%AD%E7%9A%84%E4%B8%87%E8%83%BD%E5%BC%95%E7%94%A8%E5%92%8C%E5%AE%8C%E7%BE%8E%E8%BD%AC%E5%8F%91/#%E5%BC%95%E7%94%A8%E6%8A%98%E5%8F%A0%EF%BC%88Universal-Collapse%EF%BC%89
https://www.cnblogs.com/yinheyi/p/14853787.html#%E5%BC%95%E7%94%A8%E6%8A%98%E5%8F%A0
template < typename T> void MyFunc(T&& value) { }
上面就是万能引用 既可以用于左值引用 又可以用于右值引用
因为引用折叠特性,才有了万能引用
变量作用域
void
void *
void指针 无类型指针
(void)变量
https://blog.csdn.net/qq_33611327/article/details/77770144
浮点数是否相等
FLT_EPSILON
https://blog.csdn.net/Hodors/article/details/136497256
友元
https://blog.csdn.net/weixin_38293850/article/details/80191242
友元函数
友元类
代码块
{}把代码括起来
限制变量的生命周期
符号
1 重载
https://www.runoob.com/cplusplus/cpp-overloading.html
1赋值运算符
拷贝
移动
2 顺序
https://blog.csdn.net/zhaominyong/article/details/126268983
1.首先按照优先级
2.优先级一样 按照结合性
指针符号和自增符号结合 6种情况
https://blog.csdn.net/xingjiarong/article/details/47071225
3 常见符号
1.::
域操作符
2.&
取地址
引用
位运算
3.*
乘法
注释
指针
4 …
可变参数
5 单引号 双引号
单引号表示字符
双引号表示字符串
string
c_str()
返回字符串首地址
重载 重写
重载
一个类的多个函数
重写
派生类 对 基类
继承
本质
作用域
3种方式
调用
1.有什么
就是本质里面的图
变量值决定
2.能访问什么
变量类型决定能访问什么
3.选最近的
单继承
多继承
从左往右
继承链
从上往下
多态
条件
1.继承
2.virtual+重写
3.父类指针或者引用指向子类对象
本质
没有vitual 不会调用子类
加上vitual 调用子类
switch语句
https://www.runoob.com/cplusplus/cpp-switch.html
for循环
1 2
| for ( init; condition; increment ) for (auto &x : my_array)
|
初始化
1.{}
普通变量
自定义对象
调用普通的构造函数
classname instancename= {参数列表}
const classname instancename= {参数列表}
const classname& instancename= {参数列表} 和上面区别??
classname instancename {参数列表}
注释
单行 //
多行 / /
类型转换
https://blog.csdn.net/shuzfan/article/details/77338366
1.隐式
直接来
2.显示
( )
static_cast
dynamic_cast
const_cast
reinterpret_cast
3 向上 向下
基类 -> 派生
派生 -> 基类
模板
类型模板参数
就是变量类型不确定
1 函数模板
2 类模板
非类型模板参数
https://blog.csdn.net/lanchunhui/article/details/49634077
就是值不确定
1 函数模板
2 类模板
可变参数模板
https://blog.csdn.net/qq_62390970/article/details/131277193
参数数量可变的 函数模板和类模板
enum
枚举数据类型
特殊的类
struct
https://blog.csdn.net/bytxl/article/details/48340691
union
各变量互斥
抽象类/接口
至少有一个纯虚函数
有纯虚函数的类不能实例化
宏定义
ifndef define endif
https://www.cnblogs.com/challenger-vip/p/3386819.html
define
作用
预处理阶段 做 简单替换
define add(x,y) (x+y)
2 add(1,2) -> 2 (x+y)
符号介绍
无参
有参
嵌套
function,bind
https://blog.csdn.net/weixin_44378800/article/details/115210731
封装函数
然后调用
类访问修饰符
https://www.runoob.com/cplusplus/cpp-class-access-modifiers.html
public:类内类外都可以访问
private:类内,友元
protected:和private类似,区别是protected派生类可以访问
使用cpp文件的东西
1.
.cpp-> .h
include .h
2.
extern