const * int p:
Const int 、int const*、const int &
const int* p-----p是指针变量,可以被赋值指向另一个地址,p指向的变量是常量,不能被修改。
int const p-----p是常量指针,不能修改它的指向,可以修改p的值
const int &-----代表该引用为常引用,被引用的对象不可改变。若是在形参中使用,则不可达到在函数里面修改变量值的目的
虚函数:
虚函数是C++中用于实现多态(polymorphism)的机制。核心理念就是通过基类访问派生类定义的函数。 它虚就虚在所谓“推迟联编”或者“动态联编”上,一个类函数的调用并不是在编译时刻被确定的,而是在运行时刻被确定的。由于编写代码的时候并不能确定被调用的是基类的函数还是哪个派生类的函数,所以被成为“虚”函数。虚函数只能借助于指针或者引用来达到多态的效果。
[C++对象的内存布局]
:不含virtural function的C++ struct(class)和C struct的内存布局是一样的;位置上struct中的各个字段在内存中的位置随着他们的声明顺序依次递增,大小上一种结构类型的大小是它所有字段的大小以及字段之间或字段尾部的填充区大小之和。填充区保证struct的每个字段都能符合各自的内存对齐要求;
C++的内存布局规则 三点(3关于虚函数):
C++对象的内存布局规则
-
非静态数据成员被配置于每一个对象实例(class object)之内,静态数据成员被存放在所有的对象实例之外。
-
静态和非晶态的方法成员也存放在所有的对象实例之外。
-
虚拟方法virtural function以两个步骤支持
3.1. 每一个类class产生出一堆指向virtual functions的指针,存放在表格中,称为virtual table (vtbl)
3.2. 每一个对象实例被添加了一个指针,指向相关的virtual table。这个指针通常称为vptr。
Vptr的设定setting和重置resetting由每一个类的构造器,析构器,赋值运算符自动完成。
每一个类所关联的type_info object也经由virtural table 指出,通常放在表格的第一个slot处。
C++内存对齐的原则和作用
struct/class/union内存对齐原则有四个:
1).数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小或者成员的子成员大小(只要该成员有子成员,比如说是数组,结构体等)的整数倍开始(比如int在32位机为4字节, 则要从4的整数倍地址开始存储),基本类型不包括struct/class/uinon。
2).结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部"最宽基本类型成员"的整数倍地址开始存储.(struct a里存有struct b,b里有char,int ,double等元素,那b应该从8的整数倍开始存储.)。
3).收尾工作:结构体的总大小,也就是sizeof的结果,.必须是其内部最大成员的"最宽基本类型成员"的整数倍.不足的要补齐.(基本类型不包括struct/class/uinon)。
4).sizeof(union),以结构里面size最大元素为union的size,因为在某一时刻,union只有一个成员真正存储于该地址。
内存对齐的主要作用是:
1、 平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。
2、 性能原因:经过内存对齐后,CPU的内存访问速度大大提升。
C++11新特性:
关键字:auto nullptr(auto做关键字返回值只能用于定义函数,不能用来声明函数) for循环语法:for (auto number : numbers)
STL容器:array 多维数组用,相对于数组增加了迭代器
forward_list使用list和forward_list比使用array、vector和deque效率要高很多
unordered_map unordered_set: (map红黑有序适用有顺序要求 unordered_map哈希无序,内存占用大,适用查找 具体见)unordered_set和set类似,见
map和set区别 set有序无重复
智能指针内存管理
shared_ptr weak_ptr unique_ptr
thread
增加了thread接口 以前,C++的多线程编程均需依赖系统或第三方接口实现,一定程度上影响了代码的移植性。C++11中,引入了boost库中的多线程部分内容,形成C++标准
封装了原子数据类型原子数据类型不会发生数据竞争,能直接用在多线程中而不必我们用户对其进行添加互斥资源锁的类型。从实现上,大家可以理解为这些原子类型内部自己加了锁
condition variable C++11中的std::condition_variable就像Linux下使用pthread_cond_wait和pthread_cond_signal一样,可以让线程休眠,直到别唤醒,现在在从新执行
lambda表达式:
nst * int p:](https://blog.csdn.net/sunhero2010/article/details/49429267)
Const int* 、int const*、const int & const int p-----p是指针变量,可以被赋值指向另一个地址,p指向的变量是常量,不能被修改。int const p-----p是常量指针,不能修改它的指向,可以修改p的值const int &-----代表该引用为常引用,被引用的对象不可改变。若是在形参中使用,则不可达到在函数里面修改变量值的目的 虚函数:虚函数是C++中用于实现多态(polymorphism)的机制。核心理念就是通过基类访问派生类定义的函数。 它虚就虚在所谓“推迟联编”或者“动态联编”上,一个类函数的调用并不是在编译时刻被确定的,而是在运行时刻被确定的。由于编写代码的时候并不能确定被调用的是基类的函数还是哪个派生类的函数,所以被成为“虚”函数。虚函数只能借助于指针或者引用来达到多态的效果。[C++对象的内存布局]:不含virtural function的C++ struct(class)和C struct的内存布局是一样的;位置上struct中的各个字段在内存中的位置随着他们的声明顺序依次递增,大小上一种结构类型的大小是它所有字段的大小以及字段之间或字段尾部的填充区大小之和。填充区保证struct的每个字段都能符合各自的内存对齐要求;C++的内存布局规则 三点(3关于虚函数):C++对象的内存布局规则 1. 非静态数据成员被配置于每一个对象实例(class object)之内,静态数据成员被存放在所有的对象实例之外。2. 静态和非晶态的方法成员也存放在所有的对象实例之外。3. 虚拟方法virtural function以两个步骤支持3.1. 每一个类class产生出一堆指向virtual functions的指针,存放在表格中,称为virtual table (vtbl)3.2. 每一个对象实例被添加了一个指针,指向相关的virtual table。这个指针通常称为vptr。Vptr的设定setting和重置resetting由每一个类的构造器,析构器,赋值运算符自动完成。每一个类所关联的type_info object也经由virtural table 指出,通常放在表格的第一个slot处。C++创建实例对象的方法C++内存对齐的原则和作用struct/class/union内存对齐原则有四个:1).数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小或者成员的子成员大小(只要该成员有子成员,比如说是数组,结构体等)的整数倍开始(比如int在32位机为4字节, 则要从4的整数倍地址开始存储),基本类型不包括struct/class/uinon。2).结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部"最宽基本类型成员"的整数倍地址开始存储.(struct a里存有struct b,b里有char,int ,double等元素,那b应该从8的整数倍开始存储.)。3).收尾工作:结构体的总大小,也就是sizeof的结果,.必须是其内部最大成员的"最宽基本类型成员"的整数倍.不足的要补齐.(基本类型不包括struct/class/uinon)。4).sizeof(union),以结构里面size最大元素为union的size,因为在某一时刻,union只有一个成员真正存储于该地址。**内存对齐的主要作用是:**1、 平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。2、 性能原因:经过内存对齐后,CPU的内存访问速度大大提升。C++11新特性:关键字:auto nullptr(auto做关键字返回值只能用于定义函数,不能用来声明函数) for循环语法:for (auto number : numbers)STL容器:array 多维数组用,相对于数组增加了迭代器 forward_list使用list和forward_list比使用array、vector和deque效率要高很多 unordered_map unordered_set: (map红黑有序适用有顺序要求 unordered_map哈希无序,内存占用大,适用查找 具体见)unordered_set和set类似,见 map和set区别 set有序无重复 智能指针内存管理 shared_ptr weak_ptr unique_ptr thread 增加了thread接口 以前,C++的多线程编程均需依赖系统或第三方接口实现,一定程度上影响了代码的移植性。C++11中,引入了boost库中的多线程部分内容,形成C++标准 封装了原子数据类型原子数据类型不会发生数据竞争,能直接用在多线程中而不必我们用户对其进行添加互斥资源锁的类型。从实现上,大家可以理解为这些原子类型内部自己加了锁 condition variable C++11中的std::condition_variable就像Linux下使用pthread_cond_wait和pthread_cond_signal一样,可以让线程休眠,直到别唤醒,现在在从新执行
lambda表达式:
组成捕获列表(lambda所在函数中的局部变量的列表)、形参列表、返回类型、函数体
->return type{}
进程和线程对比
关系和区别
进程使用的内存地址可以上锁,即一个线程使用某些共享内存时,其他线程必须等它结束,才能使用这一块内存。-“互斥锁”
进程使用的内存地址可以限定使用量
进程和线程间通信方式,数据交互:
进程的交互:通过TCP/IP的端口实现。进程的地址空间独立,两个进程中的地址即使值相同,实际指向的位置也不同。进程间的通信一般通过操作系统的公开区进行。
线程的交互:有一大块共享的内存,多线程共享地址空间和数据空间,所以多个线程间的通信是一个线程的数据可以直接提供给其他线程使用,而不必通过操作系统(内核)的调度。只要指针是同一个,就可以看到各自的内存。
线程通信目的主要用于线程同步,没有类似进程通信中的用于数据交换的通信机制。
进程通信方式主要有----管道、信号、消息队列、套接字socket、共享内存(共享内存是最快的IPC方式,,它是针对其他进程间通信方式运行效果低而专门设计的。它往往与其他通信机制,如信号量配合使用,来实现进程间的同步和通信)
线程通信方式主要包括:锁机制、信号、信号量
进程的内存布局
线程共享哪些进程的内存布局:
线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈,状态字),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源----包括该进程的地址空间,一个进程有一个运行时堆,为进程中所有线程共享。
线程共享资源------地址空间,全局变量,打开的文件,子进程,闹铃,信号,记账信息。
线程管理:
将线程共有的信息存放在进程控制块中,将线程独有的信息存放在线程控制块中
多线程访问堆段会出现什么问题,如何解决这些问题(信号量、锁):
互斥锁和条件变量,信号量
多线程会不会导致程序崩溃:
1.线程调用服务后没有sleep 一直占用cpu,程序直接被杀死
2.临界区section未初始化,导致线程争用,程序崩溃
子线程崩溃进程会崩溃吗:
不一定崩。线程崩溃的本质就是内存出错。而内存出错有时不会引起其他线程出错的,如果崩溃的线程也就是出错的内存没有被其他线程访问,也就不会产生问题,但有时候会打乱其他线程的内存。
程序会因为什么崩溃:
读取未赋值的变量;函数栈溢出,数组访问越界,指针的目标对象不可用,参数错误;
虚拟内存的作用
虚拟内存提供了三个重要的能力: 缓存,内存管理,内存保护
-
将主存视为一个存储在磁盘上的地址空间的高速缓存,在主存中只保存活动区域,并根据需要在磁盘和主存之间来回传送数据
-
为每个进程提供了一致的地址空间,简化内存管理
-
保护了每个进程的地址空间不被其他进程破坏
地址空间的概念:
地址空间是一个进程可用于寻址内存的一套地址集合。每个进程都有一个自己的地址空间,并且这个地址空间独立于其他进程的地址空间(除了在一些特殊情况下进程需要共享它们的地址空间外)。
虚拟地址和分段分页:
虚拟地址就是,进程创建加载的时候,自身感知获得了一个连续的内存地址空间,然而实际上内核之分配了一个逻辑上的虚拟内存空间,并且对虚拟内存和磁盘通过mmap做映射关系,对虚拟内存和物理内存的映射关系;等到程序真正运行的时候,需要某些数据,并不在虚拟内存中,才会触发缺页异常,进行数据拷贝。
指针能不能访问0x0
不能,不能对内存为0的地址取地址