C++
-
const
修饰指针
const int* p不可改变指针值
int* const p不可改变p指向
修饰引用:const string& str
修饰成员函数void func() const {} 不可改变成员变量(const ClassName *this) -
static
修饰全局变量&函数:限定在当前编译单元
修饰局部变量:开在静态区,只初始化一次,可用域为当前范围
修饰成员函数:不可访问非静态成员,只能用类名调用,没有this
修饰成员变量:只能类名调用,在静态区。
在main函数执行之前分配内存。 -
inline
复制函数代码
调用函数不压栈,直接映射参数&返回值
类声明中函数都是inline
建议编译器inline,有循环递归switch的不inline
乱用会代码膨胀,且修改后重新编译所有调用
虚函数可以内联但是失去运行时多态,只能className a;a.test(); -
this
非静态函数中,指向调用它的对象,不可赋值(ClassName* const this)
属于非静态成员函数默认第一个参数,可以std::bind -
volatile
编译器会自动优化如int a = 2;b=a+2;cout<<b;
不将a写入内存直接当作2调用。
如果在b=a+2;前 a被其他线程或某种原因修改则出错
声明后禁止编译器编译优化,强制写入读出内存。
可以修饰指针 const -
sizeof
数组sizeof为数组空间大小
指针sizeof为指针本身大小(一半为4) -
内存对齐
结构体中存在内存对齐,假设pragma pack设定值为p
当前类型大小为q
为当前变量开空间时遵循开头位置offset被min(p,q)整除
总开辟空间遵循可以被max({q},p)整除
如
int a;char b;char c;占用8
char a;int b;char c;占用12
#prama pack()可以设置为1,2,4,8等
位域:限制某类型变量只占用若干二进制位,int a:2; a只占用两个bit -
extern
可以在其他编译单元使用,可以代替部分include的工作。
extern “C”{ … } 在c++中调用c风格代码 -
explicit
修饰构造函数或转换函数(重载括号运算)
可以防止隐式转换 如ClassName c = 1;会隐式调用构造函数ClassName(int)
(参数只有一个或其余均有默认值)
explicit声明后只能显示ClassName c = ClassName(1); -
friend
可以访问private,且单向。 -
using
using namespace / using namespace::name
C++11中派生类using base::base;可以重用父类构造函数
相当于derived(params) : base(args){}
还可以相当于typedef 给模板别名
template< typename T>
using Ref = std::share_ptr< T>; -
decltype
检查实体声明类型并使用
int a;
decltype(a) 为int 可以直接声明变量
可以后置声明返回值类型
template< typename IT>
auto fcn(IT a) -> decltype(a){} -
左右值引用
右值引用:字符串常量,临时对象等等
移动语义:move() 传入左/右值 返回右值引用
原理:引用折叠:除了&&+&&=&&其他均为&
传入模板函数中的左值T自带一个&
精确传递:解决传入函数参数推测类型默认为左值问题
描述不太清楚 -
define
一对一转换参数
#define test(type) #type :将type字面转为字符串
##:连接两个字面值 -
多态
编译期多态:函数&运算符重载 , 模板
运行期多态:虚函数, 类型转换(dynamic_cast)RTTI -
虚函数
虚函数表:生成对象时产生,继承时继承父类虚函数表指针
有虚函数的空类大小为4(vfptr) 无虚函数空类大小为1
重写时覆盖虚函数表的函数指针
构造函数不能虚函数:调用构造函数时没有虚表指针
虚析构函数:被继承时一定虚析构,防止泄露
纯虚函数:抽象类 -
虚继承/多继承
防止菱形继承内存重复,采用虚表,继承时继承多个父类的虚表指针
虚表存储虚基类内存偏移量 描述不清 -
内存分配
new/delete:自动调用构造/析构函数,在堆区开内存,失败返回badalloc
定位new new§ int(2);在p指针位置开内存 其实就是返回int*类型的p
malloc/free:不调用构造/析构,失败返回null,开内存位置不同于new 不清楚
对象内存限制:
只能开在堆上:私有析构函数(在栈中开时会检测构造/析构函数)
只能开在栈上:私有重载new&delete -
智能指针
shared_ptr: 可以多个指向同一对象,有引用计数,计数归零析构对象delete 实现
unique_ptr: 不可以多个指向同一对象,不可以赋值,可以右值赋值(move)赋值后销除原指针
weak_ptr: 解决share_ptr死锁问题:两个资源相互引用,无法同时析构。相当于shared_ptr的容器,不增加引用计数,通过lock获得原share指针
auto_ptr:可以赋值操作的unique 原标准中,C++11弃用 -
类型转换
const_cast: 可以删除原对象const/volatile属性
reinterpret_cast: 重新解释二进制数据,最强制转换,慎用
static_cast: 基本同c中显式转换,可以父类->子类 (不安全)
dynamic_cast: RTTI 运行时类型信息,可以父类转子类
自动检测是否可以转换(仅支持有虚函数表的类) -
RTTI相关
typeid 返回type_info 运行时对象类型
type_info对象中保存的类型信息 -
lambda表达式
[=]:接受所有值,按值
[&]:接受所有值,按引用
[a]:接受a,按值
[&a]:接受a,按引用
[&,a]:接受a按值,接受其他所有按引用
[=,&a]:接受a按引用,接受其他所有按值
[a] ( ) mutable {a++;} 按值接受a拷贝 修改a拷贝a值不变
[ ] ( )->int{return 1;} 返回值类型int -
链接库
- 静态链接:浪费内存空间,每个可执行程序对目标文件都要副本,一个模块更新需要重新编译。
- 动态链接:将对符号的重定位推迟到运行时,解决静态库的两个缺点。