指针和引用的区别
指针定义的时候不用初始化,后期也可以修改指向,占内存空间,可以有多级指针
引用定义的时候必须要初始化,后期不可以改变指向,它只是代表一个别名,不占内存,引用不能有多级引用
堆和栈的区别
堆的内存空间必须要是malloc new来申请,并且必须要用 free delete来相应的回收内存,栈的话自己会回收
new和delete是如何实现的,new 与 malloc的异同处
new底层是用malloc来实现的
如果是对象的话
1,用malloc来申请一块内存
2,然后在这块内存上调用构造函数
delete底层使用free来实现
如果是对象
1,先调用析构函数
2,干掉这块内存
C和C++的区别
C只是高级语言
C++是面向对象语言,C++多了三大特性,继承,重载,多态
C++、Java的联系与区别,包括语言特性、垃圾回收、应用场景等(java的垃圾回收机制)
语言特性的话:c++ 有指针,多继承,强制类型转换
Java 有垃圾回收机制能够自动释放掉申请的内存,而C++是以能够操作内存著称,但是很容易带来一些错误
应用场景:c++用于底层和中间件,java用于高层
Struct和class的区别
struct 默认使用 public成员权限,默认使用private成员权限
define 和const的区别(编译阶段、安全性、内存占用等)
编译阶段:define处于编译阶段直接替换,const处于运行期
安全性:define 没得类型检查,const有类型检查
内存占用:define不占用内存,const因为实质上还是一个变量所以要占用内存
在C++中const和static的用法(定义,用途)
const可以修饰函数和变量,修饰类成员函数的话就代表函数里面的成员变量都不能修改
修饰指针变量的时候又分为顶层const和底层const,分别代表内容和指向不能改变
static三大功能
1,修饰全局变量的时候,有隐藏作用,该变量只有这个源文件能够使用,可以方便变量名重复使用
2,初始化为0
3,局部持久化,可以在函数里面修饰变量的时候,能够保存上次调用的时候的值
‘’
C++中的const类成员函数(用法和意义)
在类成员函数的后面加上一个const
void f() const { }
这样代表成员函数里面的类成员不能修改,一般用于只读函数中,不想你修改值
计算下面几个类的大小:
class A {};: sizeof(A) = 1; //空的,会有一个字节,避免申请两个对象公用内存
class A { virtual Fun(){} };: sizeof(A) = 4(32位机器)/8(64位机器); //里面含有虚函数指针
class A { static int a; };: sizeof(A) = 1; //相当于空类,因为静态存储在静态区
class A { int a; };: sizeof(A) = 4;
class A { static int a; int b; };: sizeof(A) = 4;
给一个代码,求输出结果
class A
{
public:
A(int x){}
}
问:A a = 1;是否正确, 如果正确, 那么它调用了哪些函数?
转换构造函数,能够隐式转换,可以使用 explicit强制不能转
C++的STL介绍(这个系列也很重要,建议侯捷老师的这方面的书籍与视频),其中包括内存管理allocator,函数,实现机理,多线程实现等
序列式容器:vector deque list
关联式容器:set mulset map mulmap
容器配接器:queue stack priority_queue
内存分配器:allocator
C++中的重载和重写的区别:
重载:是在同一个类中,两个相同名字的函数,需要函数参数列表不相同
重写:virtual 关键字修饰的函数,子类可以再去写一遍,如果写了就使用新的这个,并且严格意义上来说这个还是属于父类,返回值,参数列表都要一样,不写就是用父类的这个
介绍面向对象的三大特性,并且举例说明每一个
重载:就是同类的时候可以重载运算符,重载函数
继承:呃,不介绍了
多态:c++使用虚函数来实现多态,可以实现上行转换和下行转换
多态的实现
在基类的函数前加上virtual关键字,在派生类中重写该函数,运行时将会根据对象的实际类型来调用相应的函数。如果对象类型是派生类,就调用派生类的函数;如果对象类型是基类,就调用基类的函数
1:用virtual关键字申明的函数叫做虚函数,虚函数肯定是类的成员函数。
2:存在虚函数的类都有一个一维的虚函数表叫做虚表,类的对象有一个指向虚表开始的虚指针。虚表是和类对应的,虚表指针是和对象对应的。
C++虚函数相关(虚函数表,虚函数指针),虚函数的实现原理(热门,重要)
推荐博文:https://blog.csdn.net/lyztyycode/article/details/81326699 这篇写的贼好
虚函数实现原理,其实就是两个组成,虚函数表和虚函数表指针
虚函数表是在类里面的,虚函数表指针属于创建的对象,如果对象想要使用虚函数的话,那么就要用指针找到相对应的虚函数,最开始虚函数指针都是指在虚函数表的第一个位置
然后虚函数在子类实现的时候有个名词叫做重写,意思也就是在原来位置重现了这个函数
单继承:
没有重写:虚函数表就是按照定义的顺序来做的虚函数表,子类继承就把子类的接在了父类后面
有重写:子类重写了父类的虚函数,那么就把父类原先那个位置的虚函数改成新的那个,这个也是为什么多态能够实现的原因,因为始终指向没有变,但是我改变了父类的虚函数表的内容
多继承:
没有重写:会拥有多个虚函数表,自己的虚函数接在了第一个虚函数表里面
有重写:会把所以父类虚函数表和重写同名的都改掉
实现编译器处理虚函数表应该如何处理
推荐博文:https://wenku.baidu.com/view/cd87c405f12d2af90242e680.html 基本能理解原理
编译器如果检测virtual关键字,那么就会创建一个虚函数表,然后如果创建对象的话就会在前面加一个字段存储虚函数表指针
如果调用虚函数,编译器会做一个简单的替换,替换成用指针求调用虚函数
析构函数一般写成虚函数的原因
如果基类指针向派生类对象,则删除此指针时,我们希望调用该指针指向的派生类析构函数,而派生类的析构函数又自动调用基类的析构函数,这样整个派生类的对象完全被释放。
若使用基类指针操作派生类,需要防止在析构时,只析构基类,而不析构派生类
构造函数为什么一般不定义为虚函数
因为调用虚函数需要虚函数指针,虚函数指针又是对象专有,但是构造函数使用虚函数的话,都没得对象就不能搞了
构造函数或者析构函数中调用虚函数会怎样
https://www.cnblogs.com/vincently/p/4754206.html
引用里面的解释的话就是:结果会变成并没有实现多态,调用的依旧会是父类的虚函数
构造:因为基类的构造在子类构造之前,所以相当于子类的虚函数指针成员什么的都还没有建造出来,所以到基类还是基类的虚函数
析构:因为到了析构里面就默认所有成员都不存在了,就和上面一个道理了
纯虚函数
纯虚函数的格式 virtual f()=0;
代表我不实现,留给子类去实现,带有纯虚函数的类也叫抽象类,不能够实例对象出来,子类必须实现,主要解决的是多态问题,面向对象的思想
动物基类 不能实现,老虎,狮子等派生类可以给出对象,所以嘛出现了纯虚函数抽象类这个东西
静态绑定和动态绑定的介绍
动态绑定时虚函数独有的,其他都是静态绑定
摘大佬的一段话‘
(1)对象的静态类型 :对象在声明时采用的类型,是在编译期确定的。
(2)对象的动态类型:目前所指对象的类型,是在运行期决定的,对象的动态类型可以更改,但对象的静态类型无法更改。
(3)静态绑定:绑定的是对象的静态类型,其特性(如函数)依赖于对象的静态类型,发生在编译期。
(4)动态绑定:绑定的是对象的动态类型,其特性(如函数)依赖于对象的动态类型,发生在运行期。
动态绑定也就是能在运行的时候一直变化,你不能知道它哪一时刻属于什么类型,调用的哪个函数,而你一个普通函数,一眼就知道你干啥了
引用是否能实现动态绑定,为什么引用可以实现
引用和指针都是在运行期确定的,普通的是编译器
引用和指针都不改变类型,只是要一个地址和内存大小,而普通的牵扯到类型转换就不太顶
深拷贝和浅拷贝的区别(举例说明深拷贝的安全性)
浅拷贝也就是把值自己拥有的值直接传给对面,但是如果成员里面有指针的时候非常不安全,因为指针的值是一个地址,相当于两个对象的指针指向同一块内存,析构的时候对同一块内存析构两下,然后造成内存泄漏,哦凉凉
深拷贝直接把它的内存都复制一份,然后指针再指向新的这块区域,对象默认拷贝和赋值都是浅拷贝
介绍C++所有的构造函数
1,普通构造函数,就是普通那样创建
2,拷贝构造函数:利用现有对象给其他对象创建 函数传参 函数返回值 都会调用拷贝构造
3,转换构造函数:就是只有一个参数,可以有默认参数,它会你赋值一个值的时候直接转换成一个对象
结构体内存对齐方式和为什么要进行内存对齐?
结构体对齐方式看你当前最大变量的内存占用字节数,然后必须是当前的倍数
因为底层读取内存块的时候,处理器只能一次读取这么大的内存块,如果变量横跨两个内存块,那么还要读取两个内存块,然后分别取出来,贼麻烦
内存泄露的定义,如何检测与避免?
内存泄漏也就是使用堆内存忘记释放掉,然后到程序外面又没有指针能够指向它,内存就这样一直被占用着,无法再次使用
避免神器:智能指针
手写实现智能指针类
https://blog.csdn.net/lizhentao0707/article/details/81156384
智能指针是为了解决掉指针所产生的内存泄漏的问题,用来代替指针的,会自动释放掉内存
有 shared_ptr auto_ptr weak_ptr unique_ptr
需要知道的是,它所实现的自动回收内存机制,是你如果要多个指针指向同一块内存区域,只能利用之前所创建的智能指针创建,利用的是拷贝构造函数和重载赋值运算来实现的
所以当两个只能指针都是拿一块内存来初始化的时候,并不会有引用计数增加的出现,这点要特别注意
手写指针还是不太熟练,明天写一个完整的出来