Skip to content

Commit fde1d35

Browse files
添加成员函数空指针调用
1 parent 45f0fb9 commit fde1d35

File tree

2 files changed

+28
-38
lines changed

2 files changed

+28
-38
lines changed

C++/C++常见知识点.adoc

Lines changed: 28 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
:toc:
33

44
// 保证所有的目录层级都可以正常显示图片
5-
:path: C++知识点总结/
5+
:path: C++/
66
:imagesdir: ../image/
77

88
// 只有book调用的时候才会走到这里
@@ -75,6 +75,7 @@ struct _Vector_impl
7575
pointer _M_end_of_storage;
7676
};
7777
----
78+
7879
- list: 双向链表
7980
- map: 底层红黑树
8081
- deque: 双端队列
@@ -86,6 +87,11 @@ struct _Vector_impl
8687

8788

8889
=== 虚函数
90+
91+
// 虚函数实现原理,这里说明
92+
93+
94+
8995
==== 虚函数实现
9096
C++多态分为静态多态(编译时多态)和动态多态(运行时多态)两大类,静态多态通过重载,模板来实现;动态多态是通过虚函数实现。
9197
虚函数通过虚函数表vtbl(virtual table)和虚函数表指针vptr(virtual table pointer)来实现动态多态。当调用一个虚函数时,被执行的代码和调用函数的对象的动态类型相一致,当一个类声明了虚函数或者继承了虚函数,这个类就会有自己的vtbl,vtbl实际上就是一个函数指针数组,有的编译器用的是链表,不过方法都差不多。vtbl中每一个元素都对应一个函数指针,函数指针指向该类的一个虚函数,实际上每一个对象都会包含一个vptr,vptr指向该类的vtbl;
@@ -305,6 +311,9 @@ Logger *lpLog = &database; // 错误,基类指针不能指向私有继承的
305311

306312
=== 内存分配
307313

314+
//C++中虚拟内存映射规则
315+
316+
308317
- 静态存储区分配。内存在程序编译期间就已经分配好,这块内存在程序整个运行期间都存在,例如全局变量,static 变量
309318
- 在栈上创建,在执行函数时,函数内部局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放,栈内存分配运算内置于处理器的指令集中,效率很高,但是分配器的内存容量有限。
310319
- 从堆上分配,亦称为动态分配,程序在运行的时候Malloc或者new申请任意多的内存,程序员自己负责在何时用free或delete释放内存,动态内存的生存期由我们决定,使用灵活,但是问题也多
@@ -331,6 +340,16 @@ f. sizeof引用是引用对象的大小,sizeof指针是指针本身的大小
331340
g. 指针和引用搞得自增(++)运算意义不一样
332341
h. 从内存分配上来看,程序为指针分配内存区域,而引用不需要分配内存区域
333342

343+
==== C++ 中为什么能用引用尽量不要用指针
344+
345+
1. 引用是变量的别名,代码清晰度更高
346+
2. 避免不必要的参数检查
347+
3. 引用无需解引用
348+
349+
其中第3点需要特别说一下,指针本身也是个变量,那么也存在自己的地址,每次通过指针调用对象,需要先通过指针变量的名字找到指针的地址,指针地址上又存储了对象所在的地址,需要取出来再找到具体对象所在的位置。
350+
351+
image::cpp/image-2024-10-15-09-48-20-744.png[]
352+
334353
==== 智能指针
335354
====
336355
智能指针:实际上行为类似于指针的类对象,它的一种通用实现方法是采用引用计数的方法
@@ -502,6 +521,7 @@ this指针是右值
502521

503522

504523
==== volatile作用
524+
505525
1. volatile关键词的第一个特性:易变性。所谓的易变性,在汇编层面反应出来,就是两条语句,下一条语句不会直接使用上一条语句对应的volatile变量的寄存器内容,而是重新从内存中读取。
506526
2. volatile关键词的第二个特性:不可优化特性,volatile告诉编译器不要对我这个变量进行各种激进的优化,甚至将变量直接消除,保证程序员写在代码中的指令一定会被执行。
507527
3. volatile关键词第三个特性:顺序性。能够保证volatile变量间的顺序行,编译器不会进行乱序优化。
@@ -800,14 +820,17 @@ class C : virtual public B
800820
A:仍然是4+1+3(补齐) = 8
801821
B:4+1+3 + 4(vptr)+1(c2)+3(补齐) = 16
802822
C;4+1+3 + 4(vptr)+1(c2)+3(补齐) + 4(vptr)+1(c3)+3(补齐) = 24
823+
803824
64位g++下:
804825
A:仍然是4+1+3(补齐) = 8
805826
B:4+1+3 + 8(vptr)+1(c2)+7(补齐) = 24
806827
C;4+1+3 + 8(vptr)+1(c2)+7(补齐) + 8(vptr)+1(c3)+7(补齐) = 40
828+
807829
vs2013下:
808830
A:仍然是4+1+3(补齐) = 8
809831
B:4+1+3 + 4(vptr)+1(c2)+3(补齐) = 16
810832
C;4+1+3 + 4(vptr)+1(c2)+3(补齐) + 4(vptr)+1(c3)+3(补齐) = 24
833+
811834
注意这里vs2013的情况表面看上去和32位g++相同,实则不然。例如去掉class B对于A的虚拟继承性
812835
****
813836

@@ -855,50 +878,17 @@ public:
855878

856879

857880

858-
859-
860-
861-
862-
863-
864-
865-
866-
867-
868-
869-
870-
871-
872-
873-
874-
875-
876-
877-
878-
879-
880-
881-
882-
883-
884-
885-
886-
887-
888-
889-
890-
891-
892881
=== 工具
893882

894883
==== sourcetrail
895-
image::../image/image-2024-07-31-09-43-05-019.png[]
896884

897-
image::../image/image-2024-07-31-09-44-08-226.png[]
885+
image::image-2024-07-31-09-43-05-019.png[]
886+
887+
image::image-2024-07-31-09-44-08-226.png[]
898888

899889
==== Understand
900890

901-
image::../image/image-2024-07-31-09-44-44-147.png[]
891+
image::image-2024-07-31-09-44-44-147.png[]
902892

903893

904894

2.94 KB
Loading

0 commit comments

Comments
 (0)