面向对象的三大特性
封装
继承
- 父类中所有的非静态成员都会被子类继承下去,只是父类的私有成员被编译器屏蔽了,访问不到。
- 可以利用开发人员工具查看对象模型
- 继承中,先构造父类,再构造子类,析构的顺序和构造的顺序完全相反
- 父类和子类有同名的成员时,可以利用域限定符来访问特定的值
- 如果子类中出现和父类同名的函数时,子类的这个函数会覆盖父类中的所有同名函数(override),如果想访问父类的,需要使用域限定符。
- 虚函数实现的底层就是虚函数表(vbtable和vbptr),具体可以看我的这篇文章:虚函数解析
多态
- 动态多态(运行时多态)的条件:有继承关系,子类重写(override)父类的虚函数
- 使用:用父类指针或者应用,指向子类的对象。
- 在多态中,通常情况下,父类的虚函数都是无意义的,主要是调用子类的重写内容,因此通常将虚函数改为纯虚函数。当类中有纯虚函数时,这个类就叫做抽象类(无法实例化对象)。
- 在使用多态时,如果子类中有属性使用到了堆空间,那么父类指针在释放时无法调用到子类的析构代码,因此父类的析构函数也应该改为虚析构函数或者纯虚析构函数。
文件操作
文件的打开方式
示例代码:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
class Person{
public:
int age = 25;
char name[64] = "张三";
};
int main(){
Person* p = new Person();
p->age = 30;
fstream out = fstream("person1.txt",ios::out|ios::binary);
out.write((const char*)p,sizeof(Person));
out.close();
fstream in = fstream("person1.txt",ios::in|ios::binary);
Person p2;
in.read((char*)&p2,sizeof(Person));
// 在win中 读出来的二进制是对的,但是在终端打印的时候会出现问题
system("chcp 65001");
cout << p2.name << " ," << p2.age <<endl;
out.close();
}
以binary方式读写文件:read,write方法
模板
-
在使用模板的时候,头文件(.h)和实现的(.cpp)文件不能分文件编写。可以写在一起成为.hpp文件。
-
类模板不能进行自动类型推导,只能用<>显示指示类型
-
类模板在模板参数列表中可以有默认参数
-
函数模板可以进行自动类型推导,所以在使用模板函数的时候不用指定模板参数类型。
STL主要分为以下六类
容器:各种数据结构,用来存放数据
-
vector:类似于数组
-
string:字符串
-
list:类似于链表,内部有空间适配器进行内存管理
-
deque:双向队列
-
set:集合(set,mutil_set,unordered_set)
-
map:映射(map.mutil_map.unordered_map)
算法
-
sort
-
find
-
copy
-
for_each
-
find_if
-
transform
-
adjacent_find:
-
binary_search:二分查找
-
merge:
-
算术生成算法(头文件:numeric)
-
集合(必须是有序序列)运算:set_intersection(交),set_union(并),set_difference(差)
迭代器:容器与算法之间的桥梁
仿函数:行为类似函数,可作为算法的某种自定义策略。
- 函数对象:重载“()”的类其对象称为函数对象,也叫仿函数。函数对象可以有自己的状态,也可以作为参数进行传递。(也可以使用function<>模板类进行传递和接收)。
- 谓词:返回bool类型的仿函数称为谓词,接收一个参数的叫一元谓词,两个参数叫二元谓词。
- STL提供了一些内建函数对象:
适配器:用来修饰容器,仿函数或者迭代器接口
- 概念:STL 提供了序列式容器,同时针对序列式容器提供了应用于不同场景的容器适配器,通俗讲适配器就是以序列式容器为底层数据结构,进一步封装了的为适应场景应用的容器。STL 中提供了三种适配器,分别为 stack,queue 和 priority_queue。