很好的面经:https://www.cnblogs.com/Y1Focus/p/6707121.html
设计模式:
参考博客:23种设计模式全解析
C 与C++区别
联系:C++是C的超集,兼容大部分C的语法的结构;
1. 面向过程 面向对象
什么是面向对象[1]
2. C和C++动态管理内存的方法不一样,C是使用malloc/free函数,而C++除此之外还有new/delete关键字
malloc/free函数与new/delete关键字区别[2]
3. C中的struct和C++的类,C++的类是C所没有的,但是C中的struct是可以在C++中正常使用的,
并且C++对struct进行了进一步的扩展,使struct在C++中可以和class一样当做类使用,而唯一和class不同的地方在于struct的成员默认访问修饰符是public,而class默认的是private;
4. C++支持函数重载,而C不支持函数重载,而C++支持重载的依仗就在于C++的名字修饰与C不同(C++才会支持不同的参数调用不同的函数)
5. C++中有引用,而C没有;
引用和指针的区别[3]
6. C++全部变量的默认链接属性是外链接,而C是内连接 ?????????
7. C中用const修饰的变量不可以用在定义数组时的大小,但是C++用const修饰的变量可以(如果不进行&,解引用的操作的话,是存放在符号表的,不开辟内存);
8. 局部变量的声明规则不同,多态,C++特有输入输出流之类
[1] 什么是面向对象
把数据及对数据的操作方法放在一起,作为一个相互依存的整体——对象。对同类对象抽象出其共性,形成类。类中的大多数数据,只能用本类的方法进行处理。类通过一个简单的外部接口与外界发生关系,对象与对象之间通过消息进行通信。程序流程由用户在使用中决定。
- 面向过程就是:
自顶向下顺序执行,逐步求精;其程序结构是按功能划分为若干个基本模块,这些模块形成一个树状结构;各模块之间的关系尽可能简单,在功能上相对独立;每一模块内部均是由顺序、选择和循环三种基本结构组成;其模块化实现的具体方法是使用子程序。程序流程在写程序时就已决定。
- 面向对象:
这种思想是将数据作为第一位,而方法或者说是算法作为其次,这是对数据一种优化,操作起来更加的方便,简化了过程。
面向对象有三大特征:封装性、继承性、多态性
补充:多态 重载
- 多态:一个对象在不同场景表现的不同状态叫做多态
- 方法重载:方法名称相同,参数个数,参数类型,参数类型的顺序。其中返回值和访问权限不能够作为方法重载的要素。
- 重载,是指允许存在多个同名方法,而这些方法的参数不同。重载的实现是:编译器根据方法不同的参数表,对同名方法的名称做修饰。对于编译器而言,这些同名方法就成了不同的方法。它们的调用地址在编译期就绑定了。
- 多态:是指子类重新定义父类的虚方法(virtual,abstract)。当子类重新定义了父类的虚方法后,父类根据赋给它的不同的子类,动态调用属于子类的该方法,这样的方法调用在编译期间是无法确定的。
抽象
至少含有一个纯虚函数的类为抽象类;
先说 基类 派生类 纯虚函数声明 定义与实现 有纯虚函数的类什么时候可以定义对象~~
抽象类只能作为派生类的基类,不能定义对象,但可以定义指针。在派生类实现该纯虚函数后,定义抽象类对象的指针,并指向或引用子类对象。
接口和抽象类的区别
1)C++中我们一般说的接口,表示对外提供的方法,提供给外部调用。是沟通外部跟内部的桥梁。也是以类的形式提供的,但一般该类只具有成员函数,不具有数据成员;
2)抽象类可以既包含数据成员又包含方法。
虚函数与纯虚函数
参考博客:https://blog.csdn.net/wang13342322203/article/details/80512330
1. 虚函数
定义一个函数为虚函数,不代表函数为不被实现的函数。基类中有实现方法
定义他为虚函数是为了允许用基类的指针来调用子类的这个函数。
它虚就虚在所谓“推迟联编”或者“动态联编”上,一个类函数的调用并不是在编译时刻被确定的,而是在运行时刻被确定的。由于编写代码的时候并不能确定被调用的是基类的函数还是哪个派生类的函数,所以被成为“虚”函数
虚函数只能借助于指针或者引用来达到多态的效果
2. 纯虚函数
纯虚函数是在基类中声明的虚函数,它在基类中没有定义,但要求任何派生类都要定义自己的实现方法。在基类中实现纯虚函数的方法是在函数原型后加“=0”
virtual void funtion1()=0
定义一个函数为纯虚函数,才代表函数没有被实现。
定义纯虚函数是为了实现一个接口,起到一个规范的作用,规范继承这个类的程序员必须实现这个函数。
[2]细数malloc/free和new/delete的十点区别
1. malloc是从堆上开辟空间,而new是从自由存储区开辟;(自由存储区是
C++抽象出来的概念,不仅可以是堆,还可以是静态存储区);
???自由存储区 堆 静态存储区
查看博客链接https://blog.csdn.net/qian27enjoy/article/details/82624031
2. malloc/free是函数,而new/delete是关键字,操作符;
3. malloc对开辟的空间大小需要严格指定,而new只需要对象名;
4. malloc开辟的空间既可以给单个对象用也可以给数组用,释放的方式都是free();
而new开辟对象数组用的是new[size] ,释放的的时候是 delete[]
(尽管内置类型可能不会引起问题,但是自定义类型的话,delete[]需要知道有
多少个对象,而这个计数就被放在这块空间的头部); ?????????
5. 返回值问题:
malloc开辟成功返回void*,需要强转,失败返回NULL;
new成功返回对象指针,失败抛出异常(这就可能会提到C++的new_handler机制),虽然为了最大程度的兼容C,C++的new也支持失败返回NULL,但是一般不被使用,大家可以了解一下)
6. 是否调用构造和析构(这点应该放在前面)
new和free不但负责开辟空间,还会调用对象的构造函数和析构函数;最好了解一下new的三种表达形式(new运算符,operator new(); placement new();)还有定位new表达式的使用;
7. 是否可以相互调用
new的实现可以用malloc,malloc的实现不可以使用new;
8. 是否可以被重载
我们可以重载自己的operator new/delete,但是不可以重载new/delete/malloc/free;
9. malloc开辟的内存如果太小,想要换一块大一点的,可以调用relloc实现,但是new没有直观的方法来改变;
10. 第十点其实前面已经提到
当new中的底层实现如果获取不到更多的内存,会触发new_handler机制,留有一个set_new_handler句柄,看看用户是否设置了这个句柄,如果设置了就去执行,句柄的目的是看看能不能尝试着从操作系统释放点内存,找点内存,如果实在不行就抛出bad_alloc异常;而malloc就没有这种尝试了;—^—!
--------------------------------------------------------------------------------------------------------------
补充:对于非内部数据类型的对象而言,光用maloc/free无法满足动态对象的要求。 对象在创建的同时要自动执行构造函数,对象在消亡之前要自动执行析构函数。 由于malloc/free是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于malloc/free。
[3] 引用和指针的区别
- 指针有自己的一块空间,而引用只是一个别名;
- 使用sizeof看一个指针的大小是4,而引用则是被引用对象的大小;
- 指针可以被初始化为NULL,而引用必须被初始化且必须是一个已有对象的引用;---- >引用不能为NULL,指针可以为NULL
- 作为参数传递时,指针需要被解引用才可以对对象进行操作,而直接对引用的修改都会改变引用所指向的对象;
- 可以有const指针,但是没有const引用;
- 指针在使用中可以指向其它对象,但是引用只能是一个对象的引用,不能被改变;
- 指针可以有多级指针(**p),而引用至于一级;
- 指针和引用使用++运算符的意义不一样
C++与JAVA区别
Java的接口更加简洁适用,同样实现某个功能,java的代码会简洁许多。