mirror of
https://github.com/Estom/notes.git
synced 2026-04-04 03:17:44 +08:00
面向对象
This commit is contained in:
@@ -36,6 +36,7 @@ const int * pci = new const int(1024);
|
||||
* 释放一块非new分配的内存,或者将相同的指针释放多次,行为是未定义。产生错误。
|
||||
* delete对象之后,指针指向的地址被释放了,指针无效。但是指针依旧保存着原先的地址。编程**悬空指针**。
|
||||
|
||||
> 所有可变长度的容器,都有自己的allcator实现动态内存管理,不需要自己手动申请和释放内存。
|
||||
|
||||
## 1 动态内存与智能指针
|
||||
> 所以智能指针使用过来做动态内存管理的。普通的局部变量及其指针,不需要智能指针。智能指针是辅助new delete来管理动态内存的。智能指针就是为了解决一下问题。
|
||||
@@ -62,18 +63,29 @@ const int * pci = new const int(1024);
|
||||

|
||||
|
||||
|
||||
## 2 动态内存管理shared_ptr
|
||||
### 智能指针陷阱
|
||||
|
||||
> 智能指针本质上不是个指针,是对动态分配的内存的指针的管理,可以通过get函数得到指向动态内存的普通指针。
|
||||
|
||||
* 不能使用相同的内置指针初始化多个智能指针
|
||||
* 不能delete get()返回的普通指针
|
||||
* 不能用get()返回的指针初始化或reset另一个智能指针。
|
||||
* 如果使用智能指针管理的资源**不是new分配的内存**,传递给他一个删除器。(new分配的动态内存对应的删除器是delete)
|
||||
|
||||
## 2 动态内存管理shared_ptr
|
||||
### shared_ptr的操作
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
|
||||
### make_shared申请内存
|
||||
|
||||
* 最安全的使用动态内存的方法,调用make_shared标准库函数。在动态内存中分配一个对象,并初始化。返回shared_ptr.
|
||||
```
|
||||
shared_ptr<int> pn = make_shared<int>(42);
|
||||
auto = make_shared<int>(42);
|
||||
auto pn = make_shared<int>(42);
|
||||
```
|
||||
|
||||
### shared_ptr拷贝和引用计数
|
||||
@@ -89,18 +101,31 @@ const int * pci = new const int(1024);
|
||||
* shared_ptr可以使用make_shared创建对象。也可以使用new返回的指针来初始化智能指针。此时不需要delete来释放。
|
||||
|
||||
```
|
||||
share_ptr<int> p2(new int(42));
|
||||
shared_ptr<int> p2(new int(42));
|
||||
shared_ptr<int> p3 = new int{42};
|
||||
```
|
||||
### shared_ptr的其他方法
|
||||
|
||||
* shared_ptr的赋值、权限转移和清空。
|
||||

|
||||
* 不能试用get初始化另外一个智能指针,也不能用get为智能指针赋值。
|
||||
|
||||
* 我们智能使用reset将智能指针指向其他的对象,不能将一个新的对象直接赋值给已经初始化的智能指针。reset函数会更新对象的引用计数,使其指向新的动态内存。
|
||||
|
||||
```
|
||||
shared_ptr<int> = new int;
|
||||
p = new int(23);//错误,不能直接赋值。
|
||||
p.reset(new int(1024));//p指向一个新的对象。
|
||||
```
|
||||
|
||||
### 智能指针和异常
|
||||
* 当触发异常后,局部变量在销毁的时候也会正常出发智能指针的销毁。
|
||||
|
||||
## 3 动态内存管理 unique_ptr
|
||||
|
||||

|
||||
* unique_ptr是弱化的shared_ptr。某个时刻只能有一个unique_ptr直线跟一个给定的对象。当unique_ptr被销毁时,它所指向的对象也被销毁。
|
||||
* unique_ptr。某个时刻只能有一个unique_ptr只有一个给定的对象。当unique_ptr被销毁时,它所指向的对象也被销毁。
|
||||
* unique_ptr需要绑定到一个new返回的指针上。直接将指针置为空,指针指向的对象就会被释放。可以使用delete释放unique_ptr
|
||||
* unique_ptr不支持普通的拷贝和赋值操作。但是可以考别或赋值一个将要被销毁的unique_ptr.例如return unique_ptr。实现控制权转移
|
||||
* unique_ptr不支持普通的拷贝和赋值操作。但是可以拷贝或赋值一个将要被销毁的unique_ptr.例如return unique_ptr。实现控制权转移
|
||||
```
|
||||
unique_ptr<int> clone(int p){
|
||||
return unique_ptr<int>(new int(p));
|
||||
@@ -131,6 +156,57 @@ if(shared_ptr<int>np = wp.lock()){
|
||||
}
|
||||
```
|
||||
|
||||
### 总结
|
||||
> 智能指针的操作包括:初始化、解引用、赋值,reset,get。其中赋值操作是一个特例,其他操作都一致:
|
||||
> * shared_ptr能在两个智能指针之间赋值。reset可以将智能指针指向新的动态内存对象。不能直接将新的动态内存对象赋值给智能指针。
|
||||
> * unique_ptr不能再两个智能指针之间赋值,但可以在即将销毁的智能指针之间赋值。不能直接将新的动态内存对象赋值给智能指针。reset可以将智能指针指向新的动态内存对象。
|
||||
> * weak_ptr能将shared_ptr和weak_ptr赋值给weak_ptr;不能将新的动态内存对象赋值给智能指针。reset会将指针置为空。
|
||||
|
||||
|
||||
## 4 动态数组
|
||||
|
||||
## 5 文本查询程序
|
||||
### 初始化动态内存数组
|
||||
```
|
||||
int * pia = new int[10];//默认初始化
|
||||
int * pia2= new int[10]();//值初始化
|
||||
int * pia3 = new int[10]{1,2,3,4,54,6,7,8,6,5};
|
||||
```
|
||||
* 申请一个大小为0的动态数组是合法的。直接定义一个大小为0的数组是不合法的。
|
||||
|
||||
### 释放动态数组
|
||||
|
||||
delete [] pa;
|
||||
|
||||
### 智能指针和动态数组
|
||||
|
||||
* unique_ptr动态数组版本
|
||||
|
||||
```
|
||||
unique_ptr<int[]> up(new int[[10]]);
|
||||
up.release();
|
||||
```
|
||||

|
||||
|
||||
## 5 allocator动态内存
|
||||
|
||||
### 简介
|
||||
* new将动态内存分配和对象构造组合在了一起。也就是说,分配动态内存的时候,必须确定这块内存上的对象。
|
||||
* allocator能够将内存分配和对象构造分离。
|
||||
* 在头文件`<memory>`中
|
||||
|
||||
### 操作
|
||||
* 主要操作如下
|
||||

|
||||
|
||||
```
|
||||
allcator<string> alloc;
|
||||
auto const p = alloc.allocate(n);//分配n个未初始化的string
|
||||
auto q = p;
|
||||
alloc.construct(q++);//*q为空字符串
|
||||
alloc.construct(q++,10,'c');//*q为cccc
|
||||
alloc.deallocate(p,n)
|
||||
```
|
||||
### allocator算法
|
||||
* 标准库为allocator定义了两个伴随算法。
|
||||

|
||||
|
||||
|
||||
BIN
C++/标准库/2021-03-06-22-29-22.png
Normal file
BIN
C++/标准库/2021-03-06-22-29-22.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 105 KiB |
BIN
C++/标准库/2021-03-06-22-34-11.png
Normal file
BIN
C++/标准库/2021-03-06-22-34-11.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 162 KiB |
BIN
C++/标准库/2021-03-06-22-42-35.png
Normal file
BIN
C++/标准库/2021-03-06-22-42-35.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 151 KiB |
71
C++/类设计者的工具/1 拷贝控制.md
Normal file
71
C++/类设计者的工具/1 拷贝控制.md
Normal file
@@ -0,0 +1,71 @@
|
||||
# 拷贝控制
|
||||
|
||||
> 目录
|
||||
> * 拷贝、赋值与销毁
|
||||
> * 拷贝控制和资源管理
|
||||
> * 交换操作
|
||||
> * 拷贝控制实例
|
||||
> * 动态内存管理类
|
||||
> * 对象移动
|
||||
|
||||
> 类的特殊函数
|
||||
> * 初始化——构造函数
|
||||
> * 拷贝——拷贝构造函数
|
||||
> * 移动——移动构造函数
|
||||
> * 赋值——拷贝赋值运算符、移动赋值运算符
|
||||
> * 销毁——析构函数
|
||||
|
||||
|
||||
## 1. 拷贝构造函数
|
||||
|
||||
### 示例
|
||||
```
|
||||
class Foo{
|
||||
Foo();
|
||||
Foo(const Foo&)//拷贝构造函数
|
||||
}
|
||||
```
|
||||
### 合成拷贝构造函数
|
||||
|
||||
* 编译器自动生成的拷贝构造函数。从给定的对象中依次将每个非static成员拷贝到正在创建的对象当中。
|
||||
|
||||
### 拷贝初始化
|
||||
|
||||
```
|
||||
string nies = string("efji");
|
||||
```
|
||||
* 当我门使用 赋值= 运算符时,发生拷贝初始化。
|
||||
* 将一个对象作为实参传递给一个非引用类型的形参
|
||||
* 从一个返回类型为费引用类型的函数返回一个对象
|
||||
* 用花括号列表初始化一个数组中的元素或一个聚合类中的成员
|
||||
|
||||
### 拷贝赋值运算符
|
||||
|
||||
* 编译器会自动生成合成拷贝赋值运算符
|
||||
* 需要重载赋值运算符。
|
||||
|
||||
## 2 析构函数
|
||||
|
||||
### 定义析构函数
|
||||
* 类的成员函数,由拨浪汉接类名构成,没有返回值,不接受参数。不能被重载,一个类只有一个析构函数。
|
||||
|
||||
```
|
||||
class Foo{
|
||||
public:
|
||||
~Foo();
|
||||
}
|
||||
```
|
||||
### 原理
|
||||
* 在一个析构函数中,首先执行函数体,然后销毁成员。成员按初始化顺序逆序销毁。
|
||||
* 智能指针成员在西沟阶段会自动销毁。
|
||||
|
||||
### 何时调用
|
||||
* 变量离开作用域被销毁
|
||||
* 一个对象被销毁
|
||||
* 容器被销毁
|
||||
* 动态对象,使用delete
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
22
C++/类设计者的工具/2 操作重载与类型转换.md
Normal file
22
C++/类设计者的工具/2 操作重载与类型转换.md
Normal file
@@ -0,0 +1,22 @@
|
||||
# 操作重载与类型转换
|
||||
|
||||
## 1 基本概念
|
||||
|
||||
### 基础
|
||||
|
||||
* 运算符时具有特殊名字的函数:由关键字operator和气候定义的运算符共同组成。
|
||||
|
||||
* 可以被重载的运算符
|
||||
|
||||

|
||||
|
||||
|
||||
## 2 输入输出运算符
|
||||
|
||||
定义重载运算符。
|
||||
```C++
|
||||
ostream &operator<<(ostream &os , const Sales data &item) {
|
||||
os << 工 tem . isbn() << " " << item. units sold << " " << item. revenue << " " << item.avg_price ();
|
||||
return os;
|
||||
}
|
||||
```
|
||||
BIN
C++/类设计者的工具/2021-03-06-23-22-55.png
Normal file
BIN
C++/类设计者的工具/2021-03-06-23-22-55.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 73 KiB |
39
C++/类设计者的工具/3 面向对象程序设计.md
Normal file
39
C++/类设计者的工具/3 面向对象程序设计.md
Normal file
@@ -0,0 +1,39 @@
|
||||
# 面向对象程序设计
|
||||
|
||||
> 面向对象的基本概念
|
||||
> * 数据抽象和封装
|
||||
> * 继承
|
||||
> * 多态(动态绑定)
|
||||
|
||||
|
||||
## 1 OOP:概述
|
||||
|
||||
### 面向对象程序设计
|
||||
|
||||
* 核心思想:
|
||||
* 数据抽象:类的接口与实现分离。
|
||||
* 继承:定义相似的类型,对相似的关系建模。实现代码重用。
|
||||
* 动态绑定:可以在以一定程度上忽略相似类型的区别。
|
||||
|
||||
### 继承
|
||||
|
||||
* 继承:联系在一起的类构成以中层次关系
|
||||
* 基类:层次关系的根部
|
||||
* 派生类:其他类则直接或间接地从基类继承而来。
|
||||
|
||||
* 虚函数:
|
||||
|
||||
## 2 定义基类和派生类
|
||||
|
||||
## 3 虚函数
|
||||
|
||||
## 4 抽象函数
|
||||
|
||||
## 5 访问控制与继承
|
||||
|
||||
|
||||
## 6 继承中的类作用域
|
||||
|
||||
## 7 构造函数与拷贝控制
|
||||
|
||||
## 8 容器与继承
|
||||
0
C++/类设计者的工具/4 模板与泛型编程.md
Normal file
0
C++/类设计者的工具/4 模板与泛型编程.md
Normal file
@@ -98,25 +98,4 @@ vector<int> b{3,4,5};//列表初始化----集合直接初始化
|
||||
Car t{3,4};//列表初始化----直接初始化,构造函数。
|
||||
vector<Car> ttt{Car(3.4),Car(5,6)};
|
||||
```
|
||||
* 所有其他初始化形式都是list initialization的特殊表现形式或者与其相关。理解的要点在于,list中的参数要么按构造函数的参数声明顺序,要么按aggregate类型成员声明顺序,逐个赋值。
|
||||
|
||||
|
||||
|
||||
|
||||
## 2 类的构造函数
|
||||
|
||||
### 默认构造函数
|
||||
### 合成默认构造函数
|
||||
### 委托构造函数
|
||||
### 拷贝构造函数
|
||||
|
||||
|
||||
### 构造函数类型和初始化的方法
|
||||
> 介绍初始化的方法、构造函数的类型、初始化执行的顺序。
|
||||
|
||||
|
||||
1. 列表初始化
|
||||
2. 委托构造函数
|
||||
3. 初始化函数体
|
||||
4. 值初始化。(在成员变量定义的时候给出的值)
|
||||
5. 默认初始化(以上情况都没有的时候)
|
||||
* 所有其他初始化形式都是list initialization的特殊表现形式或者与其相关。理解的要点在于,list中的参数要么按构造函数的参数声明顺序,要么按aggregate类型成员声明顺序,逐个赋值。
|
||||
@@ -37,4 +37,4 @@ foo_t *f = NULL;
|
||||

|
||||
|
||||
### C++中的nullptr
|
||||
* nullptr 关键字,被自动转换为各种pointer类型。但他不会不转换为任何证书类型。
|
||||
* nullptr 关键字,被自动转换为各种pointer类型。但他不会不转换为任何整型类型。防止null作为参数的时候出现函数重载的错误。
|
||||
|
||||
29
C++/面试/15.构造函数.md
Normal file
29
C++/面试/15.构造函数.md
Normal file
@@ -0,0 +1,29 @@
|
||||
|
||||
|
||||
## 2 类的构造函数
|
||||
|
||||
与类同名的,没有返回值的函数,用来创建、管理该类。
|
||||
|
||||
### 合成构造函数
|
||||
|
||||
编译器自动生成的一系列构造函数。包括以下几种
|
||||
* 合成默认构造函数
|
||||
* 当用户定义了任意类型的构造函数,编译器不再自动生成合成默认构造函数
|
||||
* 合成拷贝构造函数
|
||||
* 即是用户定义了其他类型的构造函数,编译器还会自动生成合成拷贝构造函数。
|
||||
* 合成析构函数
|
||||
|
||||
### 默认构造函数
|
||||
|
||||
无参构造函数。
|
||||
|
||||
### 拷贝构造函数
|
||||
|
||||
唯一参数是当前类类型。
|
||||
|
||||
### 移动构造函数
|
||||
|
||||
|
||||
### 委托构造函数
|
||||
|
||||
使用已有的构造函数初始化。
|
||||
@@ -11,7 +11,7 @@
|
||||
- 知识复习——语言(一周)
|
||||
- C++(primer)
|
||||
- 基础语法√
|
||||
- 标准库 STL
|
||||
- 标准库 STL√
|
||||
- 面向对象
|
||||
- 设计模式(有道云笔记,gitee 设计模式库,书)
|
||||
- effective 系列
|
||||
|
||||
Reference in New Issue
Block a user