c++ 多态
- 多态字面意思就是多种形态
- 目的是为了接口重用,分为静态多态和动态多态
- 静态多态:
- 在编译期间编译器根据参数类型可以推断出调用什么类型的函数
- 静态多态是通过函数的重载来实现的
- 动态多态:
- 动态多态是基于继承实现的,动态多态有两个实现条件
- 必须通过基类的指针或者引用去调用虚函数
- 被调用的函数必须是虚函数并且派生类中必须对基类的虚函数完成重写
- 通过虚函数来实现的
- 动态多态是基于继承实现的,动态多态有两个实现条件
- 多态字面意思就是多种形态
虚函数重写要求返回类型、函数名、参数类型一致才能重写,但也有例外情况
- https://zhuanlan.zhihu.com/p/455301660
- 协变
- 正常虚函数重写要求函数名,参数,返回值都相同,但是协变可以返回值不相同,也就是可以让基类虚函数返回基类指针或引用,派生类虚函数返回派生类指针或者引用,这就成协变
- 析构函数
- 因为在编译器中,会自动将所有对象的析构函数都转换成destructor()函数,所以在编译器看这两个析构函数就是同名函数
- 协变
- https://zhuanlan.zhihu.com/p/455301660
final和override关键字
- finnal关键字是用在父类的
- 修饰虚函数,表示该虚函数不能被重写
- 修饰类,表示该类不能被派生
- overide关键字是用在子类的
- 显示声明这个是基类虚函数的重写
- finnal关键字是用在父类的
虚函数表生成的
构造函数和析构函数里面能不能使用虚函数
构造函数能不能声明为虚函数?
- 虚函数的调用的需要虚表指针,而虚表指针是在构造函数中确定的
- 构造函数是在创建对象的时候自动调用的,不会通过父类的指针或者引用来调用构造函数
哪些函数不能被声明为虚函数?
- 内联函数
- 在函数调用处用整个函数体去替换,而virtual函数是在运行期才能够确定如何去调用的,因而inline函数体现的是一种编译期机制,virtual函数体现的是一种运行期机制。
- 静态成员函数
- 不能被继承,只属于类
- 构造函数
- 内联函数
虚表和虚表指针
- https://blog.csdn.net/lingfengtengfei/article/details/12345809
- 虚函数表
- 类的虚表会被这个类的所有对象所共享。类对象的虚表指针都指向同一个虚表
- 虚表中存放的是虚函数的地址
- 虚表指针
- 虚表指针的初始化确实发生在构造函数的调用过程中, 但是在执行构造函数体之前
为什么析构函数最好定义为虚函数
- 基类指针指向派生类对象时,delete基类指针时我们希望调用派生类的析构函数
- 析构函数定义为虚函数时可以实现动态绑定,最终执行子类的析构函数。
函数的重载、重写、重定义
- https://blog.csdn.net/tck001221/article/details/121470290
- 重载【函数名相同、函数形参or数量不同】
- 重写【虚函数】
- override 关键字:显示声明是重写的
- 重定义
- 函数名相同即可,未被定义虚函数
右值引用
- 什么是左值
- 可以被寻址到的,有名字的
- 什么是右值
- xxx
- 作用:
- 右值引用的作用是为了延长某块内存的生命周期,避免了临时对象使用完就被销毁,创建右值引用则可以避免对象的拷贝和临时对象的销毁,提高程序的运行效率。
- 应用场景
- 在函数中返回的临时对象,如果用来初始化另一个对象,如果没有定义移动构造函数,那么会调用拷贝构造函数,进行深拷贝,再将函数中的临时对象析构,如果定义了移动构造函数,那么就会进行浅拷贝,临时对象的堆内存还能接着用,但是临时对象还是会被析构掉。
- 将亡值
- xxxxxx
- 使用场景
- STL 中会有右值引用
- 减少对象拷贝
- 拷贝构造函数 && 移动构造函数【少一次调用拷贝构造函数】
- STL 中会有右值引用
- 移动语义
- 完美转发
- forward( )
- 什么是左值
push_back() 和 emplace_back()有什么区别
- https://blog.csdn.net/pengjian444/article/details/116740246
- https://www.cnblogs.com/foghorn/p/15882774.html
右值引用
https://subingwen.cn/cpp/rvalue-reference/#3-amp-amp-%E7%9A%84%E7%89%B9%E6%80%A7
左值:存储在内存中、有明确存储地址(可寻址)的数据,可用&取地址
右值:可提供数据值的数据,不一定可以寻址,例如存储于寄存器中的数据。右值可分为纯右值和将亡值,字面值就是一种纯右值,将亡值是没有名字的临时对象,即将被释放掉,例如T&&类型的函数返回值,move函数的返回值。
右值引用的作用是为了延长某块内存的生命周期,避免了临时对象使用完就被销毁,创建右值引用则可以避免对象的拷贝和临时对象的销毁,提高程序的运行效率。(其实左值引用也是为了提高效率,比如说函数传参的时候采用左值引用,就可以避免拷贝创建副本)。
右值引用的应用实例:
1)在函数中返回的临时对象,如果用来初始化另一个对象,如果没有定义移动构造函数,那么会调用拷贝构造函数,进行深拷贝,再将函数中的临时对象析构,如果定义了移动构造函数,那么就会进行浅拷贝,临时对象的堆内存还能接着用,但是临时对象还是会被析构掉。
2)如果用函数的返回值初始化一个右值引用,也是会调用移动构造函数,如果没有移动构造函数还是会调用拷贝构造函数。
右值引用的自动类型推到规则:
在泛型编程中的T和auto、decltype进行类型推导定义右值引用的时候,当且仅当初始化值为右值的时候,被初始化的值才是右值引用,否则都是左值引用或者常量类型的左值引用。
右值引用不能用来初始化右值引用,因为定义了右值引用之后,右值就被具名化了,其实就是相当于一个左值了
- 智能指针
- 为什么弃用auto_ptr
- xxxxxxxxxxx
- unique_ptr是怎么实现?
- xxxxx
- shaered_ptr的实现
- weak_ptr
- 没有weak_ptr会出现循环引用:举例子
- 怎么解决?
- 为什么弃用auto_ptr
- 虚拟地址空间
- 什么是虚拟内存【虚拟内存是什么】
- https://www.php.cn/faq/418081.html
- 虚拟内存是一种计算机系统内存管理技术。它使得应用程序认为它拥有连续可用的内存,即一个连续完整的地址空间。而实际上,它通常是被分隔成多个物理内存碎片,还有部分暂时存储在外部磁盘存储器上,在需要时进行数据交换。
- 虚拟地址空间有哪些作用【为什么要有虚拟内存】
- https://zhuanlan.zhihu.com/p/451886800
- https://www.sohu.com/a/453109141_315839
- 虚拟内存可以利用磁盘起到缓存的作用,只加载一部分到内存中,触发缺页中断即可。
- 虚拟内存可以为进程提供独立的内存空间,简化程序的链接、加载过程并通过动态库共享内存。
- 虚拟内存可以控制进程对物理内存的访问,隔离不同进程的访问权限,提高系统的安全性。
- 虚拟内存设计的发展变化
- 段页式
- 页表
- 什么是虚拟内存【虚拟内存是什么】
