1.C++语言的特点
1.1面向对象class(封装、继承、多态)。
**封装:**将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行 交互
**继承:**使用现有类的所有功能,并对这些功能进行扩展。
**多态:**父类指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数。实现多态,有二种方式,重写,重载。(继承+多态两大特性的实际应用点 虚函数,纯虚函数)
1.2运行速度快,仅比汇编慢15%左右。
1.3增加了const常量 、引用(指针起别名,实质为常量指针)、四类转换(static_cast、dynamic_cast、const_cast、reinterpret_cast)、智能指针、try-catch等。
const常量:
**const:**一般用于约束某个值或某个指针不可改变,或者放在成员函数后,定义成const的成员函数,一旦企图修改数据成员的值,则编译器按错误处理
static_cast<class *>(object);
**static_cast:**类型转换,任何具有明确定义且不包含底层const的都可以转换。
**dynamic_cast:**在静态转换的基础上进行了类型识别,一般用于父类与子类之间的类型转换。(更加安全)
**const_cast:**改变运算对象的底层const(去掉const性质)
**reinterpret_cast:**运算对象的位模式提供较低层次重新解释。
一般情况下建议使用static_cast 与dynamic_cast即可
智能指针(建议初始化方式:shared_ptr(auto)p = make_shared (0))
智能指针的作用:使用指针时更加安全,智能指针会自动帮你delete 指针,无需程序员手动delete
shared_ptr:多个指针指向同一个对象
unique_ptr:独占所指向的对象 。指针销毁时,指向的对象一并销毁
weak_ptr:指向shared_ptr所管理的对象 (弱引用)。shared_ptr的副手
auto_ptr:部分unique_ptr的特性,不建议使用
当智能指针绑定普通指针后,内存的管理责任直接交给shared_ptr。
try_catch:程序报错时使用。若异常未被捕获,将终止当前的程序。
1.4引入模板的概念(经典应用STL,Standard Template Library)。
for(vector::iterator it = v.begin(); it < v.end(); ++it)
STL库:容器,算法,迭代器
容器: 容器是用来管理某一类对象的集合。C++ 提供了各种不同类型的容器,比如 deque、list、vector、map 等。
算法:swap及其他排序算法,算法作用于容器
迭代器:容器与算法之间的中间部件,迭代器用于遍历对象集合的元素。这些集合可能是容器,也可能是容器的子集。
1.5c++11新特性
后续详细介绍这些特点…
2.C++中 struct 和 class 的区别
struct 一般用于描述一个数据结构集合,而 class 是对一个对象数据的封装
struct 中默认的访问控制权限是 public 的,而 class 中默认的访问控制权限是 private 的
struct 默认是公有继承,而 class 是私有继承
class 关键字可以用于定义模板参数,就像 typename,而 struct 不能用于定义模板参数
3.导入C函数的关键字是什么(extern c),C++编译时和C有什么不同**
extern "C"的主要作用就是为了能够正确实现C++代码调用其他C语言代码。加上extern "C"后,会指示编译器这部分代码按C语言的进行编译,而不是C++的。
C++支持函数重载,编译函数的过程中会将函数的参数类型加到编译后的代码中,而不仅仅是函数名;C语言不支持函数重载,因此编译C语言代码的函数一般只包括函数名。
4.C++从代码到可执行二进制文件
预编译、编译、汇编、链接
预编译:过滤所有的注释,#define删除,生成汇编代码
汇编:汇编代码转变成机器可以执行的指令(01001)。
链接:将不同的源文件产生的目标文件进行链接,从而形成一个可以执行的程序。
静态链接(库):windows下是lib文件,调用需.h和.lib文件 Linux下以.a为后缀。
动态链接(库):windows下是dll文件 ,调用需.h .lib .dll 文件。 Linux下以.so为后缀。
5.static关键字的作用
定义全局静态变量和局部静态变量:在变量前面加上static关键字。初始化的静态变量会在数据段分配内存,未初始化的静态变量会在BSS(静态内存分配)段分配内存
C++标准规定:全局或静态对象当且仅当对象首次用到时才进行构造。
static用在函数前(0就可以直接通过类的作用域的方式来调用,无需对类进行实例化后再调用。
6.数组和指针的区别
使用时可将一维数组与指针等同看待,二维指针与指针的指针等同。
(1)数组:数组是用于储存多个相同类型数据的集合。 数组名是首元素的地址。
(2)指针:指针相当于一个变量,但是它和不同变量不一样,它存放的是其它变量在内存中的地址。 指针名指向了内存的首地址。
赋值:同类型指针变量可以相互赋值;数组不行,只能一个一个元素的赋值或拷贝
数组在内存中是连续存放的,开辟一块连续的内存空间。而指针的存储空间不能确定
7.什么是函数指针,如何定义函数指针,有什么使用场景
函数指针就是指向函数的指针变量。每一个函数都有一个入口地址,该入口地址就是函数指针所指向的地址。
int func(int a);
int (*f)(int a);
f = &func;
数指针的应用场景:回调(callback)。我们调用别人提供的 API函数(Application Programming Interface,应用程序编程接口),称为Call;如果别人的库里面调用我们的函数,就叫Callback。
8.什么是野指针,怎么产生的,如何避免?
指针指向的位置是不可知的
释放内存后指针不及时置空(野指针),依然指向了该内存,那么可能出现非法访问的错误
9.静态局部变量,全局变量,局部变量的特点,以及使用场景
全局变量:全局作用域,可以通过extern作用于其他非定义的源文件。
静态全局变量 :全局作用域+文件作用域,所以无法在其他文件中使用。
局部变量:局部作用域,比如函数的参数,函数内的局部变量等等。
静态局部变量 :局部作用域,只被初始化一次,直到程序结束。
10.内联函数和宏函数的区别
宏定义是没有类型检查的,内联函数在编译的时候会进行类型的检查
宏定义不是函数,但是使用起来像函数,预处理器用复制宏代码的方式代替函数的调用
内联函数在调用时,是将调用表达式用内联函数体来替换。避免函数调用的开销
11.new和malloc的区别,各自底层实现原理。
new是操作符,而malloc是函数。
new在调用的时候先分配内存,在调用构造函数,释放的时候调用析构函数;而malloc没有构造函数和析构函数。
malloc需要给定申请内存的大小;new会调用构造函数,不用指定内存的大小。
12.const和define的区别
const定义的常量需要额外的内存空间;define定义的常量,并不会存放在内存中。
const定义的常量是带类型的;define定义的常量不带类型。因此define定义的常量不利于类型检查。
**13.C++中函数指针和指针函数的区别。int (f)(int a); int fun(int x,int y);
指针函数本质是一个函数,其返回值为指针。 函数指针本质是一个指针,其指向一个函数。
13 C++有几种传值方式,之间的区别是什么? 值传递、引用传递、指针传递
14c++内存分配
堆和栈: 栈由操作系统自动分配释放 ,存放函数的参数值,局部变量的值等;堆由程序员分配释放。
C++的内存管理: 堆、栈、自由存储区、全局/静态存储区和常量存储区
(1)栈(stack):由编译器进行管理,自动分配和释放,存放函数调用过程中的各种参数、局部变量、返回值以及函数返回地址。操作方式类似数据结构中的栈。
(2)堆(heap):用于程序动态申请分配和释放空间。C语言中的malloc和free,C++中的new和delete均是在堆中进行的。正常情况下,程序员申请的空间在使用结束后应该释放,若程序员没有释放空间,则程序结束时系统自动回收。注意:这里的“堆”并不是数据结构中的“堆”。
(3)全局(静态)存储区:分为DATA段和BSS段。DATA段(全局初始化区)存放初始化的全局变量和静态变量;BSS段(全局未初始化区)存放未初始化的全局变量和静态变量。程序运行结束时自动释放。其中BBS段在程序执行之前会被系统自动清0,所以未初始化的全局变量和静态变量在程序执行之前已经为0。
(4)文字常量区:存放常量字符串。程序结束后由系统释放。
(5)程序代码区:存放程序的二进制代码。
15.内存泄露及解决办法
申请了一块内存空间,使用完毕后没有释放掉。(1)new和malloc申请资源使用后,没有用delete和free释放;(2)子类继承父类时,父类析构函数不是虚函数
16.内存对齐?
为了使CPU能够对变量进行快速的访问(提高CPU访问数据的效率问题),变量的起始地址应该具有某些特性,即所谓的“对齐”,比如4字节的int型,其起始地址应该位于4字节的边界上,即起始地址能够被4整除,也即“对齐”跟数据在内存中的位置有关。