指针管理的困难:
1. 资源释放了,指针没有置空
(1)野指针
指针没有置空,后续接着使用。
(2)指针悬挂
多个指针指向同一个资源,其中一个指针释放了资源,也置空了,其他指针不知道该情况
(3)踩内存
资源已经释放,这块内存有了其他内容,还按照之前的方式去访问。
2.没有释放资源,引发内存泄漏
3.重复释放资源,引发core dump
RAII思想(Resource Acquisition Is Initialization):利用对象的生命周期来管理指针。
shared_ptr
解决指针悬挂的问题,只有引用计数为0,才调用析构函数。
使用场景:在容器中管理指针/资源需要通过函数进行传递
shared_ptr共享它指向的对象,多个shared_ptr可以指向相同的对象,在内部采用计数机制来实现
当新的shared_ptr与对象关联时,引用计数增加1。
当shared_ptr超出作用域时,引用计数减1。当引用计数变为0时,表示没有任何shared_ptr与对象关联,则释放该对象。
unique_ptr
一个资源只有一个指针指向它,unique_ptr独享它指向的的对象,同时只有一个unique_ptr指向同一个对象。当这个unique_ptr被销毁时,指向的对象也被销毁
不要用同一个裸指针初始化多个unique_ptr
get()方法返回裸指针
不要用unique_ptr管理不是new分配的内存
weak_ptr: 如何解决shared_ptr的循环引用问题
智能指针是类模板,在栈上创建智能指针对象
把普通指针交给智能指针对象。
volatile用于声明一个变量,告诉编译器该变量值容易发生改变,在编译、读取、存储该变量的时候都不要做任何优化,因此编译后的程序每次需要存储或读取这个变量的时候,都会直接从变量地址中读取存储数据,不做优化,在做嵌入式开发的时候,因为有时变量地址有可能是系统的一个外设地址,他的值的变化并不在程序控制范围内,随时有可能变化,因此需要对他进行声明,每次读取或者存储直接对地址进行操作。
变量如果加了 volatile 修饰,则会从内存重新装载内容,而不是直接从寄存器拷贝内容。
重载是同一个作用域下函数名称相同,参数不同,重写是子类重写父类的方法
函数的返回值不可以作为函数重载的条件:两个函数只有返回值不同,不符合重载的条件
当函数重载碰到默认参数,会出现二义性。
引用就是变量的别名
引用必须初始化
引用在初始化后不可以修改
引用与指针的区别:
引用作函数的返回值:不要返回局部变量的引用,
函数调用可以作为左值:如果函数的返回值是引用,这个函数调用可以作为左值。
引用的本质在c++内部的实现是一个指针常量。
在函数形参列表中,可以加const修饰形参,防止形参改变实参
const int *p 常量指针
指针的指向可以更改,指针指向的内容不可以更改。
int * const p 指针常量
指针的指向不可以更改,指针指向的内容可以更改。
const int * const p
指针的指向和指针指向的内容不可以更改。
浅拷贝带来的问题是:堆区的内存重复释放。
https://www.cnblogs.com/hyacinthLJP/p/16041690.html
C++结构体字节对齐_c++ 结构体对齐_桃溪小小生的博客-CSDN博客
*&首先是一个指针,然后&代表是这个指针的引用。指针的引用其实是指针的一个别名,和指针具有相同的地址。
c++是大小写敏感的,也是拼写敏感的。
强制类型转换不会修改变量本身,而是创建一个新的、指定类型的值。
父类中所有非静态成员属性都会被子类继承。
父类中私有成员属性是被编译器给隐藏了,因为访问不到,但确实被继承了。
子类和父类中有同名成员时,子类中可以直接访问子类中同名成员,加作用域可以访问父类中同名成员。
当子类和父类中有同名成员函数,子类会隐藏父类中所有同名成员函数,加作用域可以访问父类中同名成员函数。
菱形继承问题
动态多态的条件:
动态多态原理:
虚函数表指针(vfptr)指向虚函数表(vftable)。动态多态会让子类重写父类的虚函数表。
vf=virtual function
类中只要有一个纯虚函数就成为抽象类。抽象类是在虚函数后面加上 = 0 。
抽象类的两个特点:
多态时通过父类指针释放子类对象时,如果子类中有堆区的数据成员,无法通过父类指针释放,父类指针只会调用父类的析构函数,不会调用子类的析构函数。这时需要将父类的析构函数声明为虚函数,即虚析构函数,这样父类指针析构时就会既调用父类的析构函数,也会调用子类的析构函数。
纯虚析构函数不仅需要声明,也需要实现,但是需要在类外实现。类中如果有纯虚析构函数也是抽象类。
继承时,先调用父类的构造函数,再调用子类的构造函数。析构顺序与构造顺序相反。
c++ vector.end()指向vector()最后一个元素的下一个位置
假如基类的指针指向派生类的对象,那么这个指针可以通过dynamic cast变成派生类的指针,并且是操作安全的;假如基类的指针指向基类的对象,那么这个指针不能通过dynamic cast的类型检查,新指针会是空指针,但是这个指针可以通过static cast变成派生类的指针,但是操作会出现问题。
父类中的protected的内容子类也可以访问。
父类中的private的内容子类不可以访问。
struct默认权限为public,class默认权限为private。