1、C和C++的区别
C | C++ | |
面向 | 过程 | 对象 |
注重 | 程序的实现逻辑 | 程序的整体设计 |
内容 | C语言采用了一种有序的编程方法——结构化编程:将一个大型程序分解为一个个小型的,易于编写的模块,所有模块有序调动,形成了一个程序的完整的运行链 | C++将问题分解为各个对象,建立对象的目的不是为了完成一个步骤,而是为了描述某个事物在整个解决问题中的行为,更注重程序的整体设计,方便程序的后期维护、优化和管理,让一个功能尽可能的通用。应对需求的变化,本意是处理大型复杂系统的设计和实现 |
优点 | 性价比比面向对象高,比如单片机、嵌入式开发、Linux/Unix等一般采用面向过程开发,性能是最重要的因素 | 易维护、易复用、易扩展,由于面向对象有封装、继承、多态的特性,可以设计出低耦合的系统,使系统更加灵活,更加易于维护 |
缺点 | 没有面向对象易维护、易复用、易扩展 | 因为类调用时需要实例化,开销比较大,比较消耗资源,性价比比面向过程低 |
2、C++面向对象有哪些特征
封装 | 封装是指将对象的属性和方法结合成一个独立的系统单位,隐藏对象的内部细节,只保留有限的对外接口,这样可以保护数据不受外部随意访问或修改,同时简化编程接口,提高代码的可维护性和安全性 |
继承 | 继承允许一个(子类)继承另一个类(父类)的属性和方法,这样可以实现代码的重用,提高开发效率,在C++中,继承分为公有继承、保护继承和私有继承,分别定义了基类成员在派生类中的访问权限 |
多态 | 多态指在一般类中定义的属性或行为被特殊类继承后,可以具有不同的数据类型或表现出不同的行为,这样可以在不改变程序结构的情况下,使用相同的方式调用不同对象的方法,C++中支持两种多态性,编译期多态和运行期多态。编译器多态通过函数重载实现,运行期多态通过虚函数实现 |
3、堆和栈的区别
堆 | 栈 | |
存放变量类型 | 全局变量 | 局部变量 |
存放内容 | 需要动态分配的数据结构,如字符串、对象和动态数组 | 函数调用时的临时变量、函数返回地址等信息,主要用于内存的临时分配 |
内存区域 | 不连续,(链表存储空闲内存地址) | 连续 |
管理方式 | 程序员自行负责,使用后必须手动释放 | 按照”先进后出“的原则进行管理 |
申请效率 | 慢 | 快 |
生长方向 | 向高地址扩展数据结构 | 向低地址扩展数据结构 |
空间大小 | 空间较大 | 空间较小 |
申请大小 | 动态申请释放,没有特定限制 | 操作系统指定大小,被操作系统限制 |
分配方式 | 当关键字malloc或new执行时,才会被分配空间,只能动态分配 | 当函数被执行时,形参和函数内部的局部变量会一起被创建出来,可以动态和静态分配 |
访问方式 | 只能用指针读取数据 | 可以使用变量名或指针读取数据 |
存在周期 | 存在时间较长,需要人为清理和回收 | 存在时间取决于存在作用域,当执行程序离开时,该所在的作用域将被回收 |
稳定性 | 不稳定,容易造成内存泄露 | 稳定 |
4、怎么确定new和malloc的成功和失败
malloc | new | |
成功 | 如果成功,返回void*,需要手动强转为需要的类型 | 返回对象类型的指针,类型和对象严格匹配,无需类型转换 |
失败 | 返回NULL指针 | 抛出bad_alloc异常(程序异常错误提示框) |
使用new申请内存后,一定要delete,并将指针赋空,否则会造成内存空间的浪费
5、C语言中已经有了malloc,为什么C++中要加入new,不直接使用malloc
malloc和free使用时需要显式的指定申请空间的大小,而new和delete不需要
malloc申请后的类型需要强转为所需要的类型,new申请后的返回值不需要强转
6、malloc和new的区别
相同点
都在堆区中分配空间 |
都需要手动释放 |
返回的都是堆区的首地址,需要用指针来接收 |
不同点
malloc—free | new—delete | |
初始化 | malloc不能在申请空间的同时进行初始化 | new先调用operator new()函数,申请足够的内存空间 然后调用类型的析构函数,初始化成员对象,最后返回自定义的类型的指针 delete先调用析构函数,最后调用operator delete()函数释放空间 |
类成员 | 单纯的申请空间,不会调用构造、析构函数 | 申请结构体、类空间时,自动调用构造、析构函数 |
属性 | 是C中的库函数,需要引入对应的头文件 | 是C++中的关键字,使用时只需要编译器的支持就可以 |
用法 | #include<malloc.h> int* p1=(int*)malloc(sizeof(int)); | int* p2=new int; |
参数 | 传递的是申请空间的大小,需要指定申请空间的大小 | 传递的是类型,可以自动计算大小 当new出来的是数组时,delete时用delete[]变量名的方式进行释放,[]无需写数组长度 |
返回类型 | 返回void*,需要强转为所需要的类型 | 直接申请对象类型的指针,不需要强转 |
分配失败 | 返回NULL指针 | 抛出bad_alloc异常 |
重载 | 是函数,不可以重载,但可以重写 | 是操作符,可以重载 |
内存区域 | 操作符从自由存储区为对象分配内存空间 自由存储区不仅可以是堆,还可以是静态存储区 |
7、深拷贝和浅拷贝的区别、优缺点
浅拷贝 | 深拷贝 | |
拷贝对象与被拷贝对象是否在同一地址 | 创建一个新对象时,把对象的初始属性都复制一份,若是存在引用类型,则拷贝的是其内存地址,当它的值发生改变时,另一个的值也会受到改变 | 是将对象从内存中完全拷贝出来,并且重新开辟出一片空间来进行存放,当其中一个值发生改变时并不会影响另一个的值,两者互不影响 |
优点 | 在简单的情况下,浅拷贝与深拷贝相同,且无内存浪费问题 | 在有指针存在的情况下,可解决浅拷贝的双重释放等问题,在改变新的数组(对象)时,不会改变原数组(对象) |
缺点 | 多个对象可能指向同一块内存地址,析构时可能造成内存重复释放等问题 | 在不涉及指针等的情况下,单纯的访问数据会造成内存浪费 |
8、继承下定义子类对象,构造,析构的顺序及原因
10、什么是多态
多态的概念
相同的行为方式可能导致了不同的行为结果,同一行语句展现了多种表现形态 |
父类的指针可以指向任何继承于该父类的子类对象,且父类指针具有子类对象的形态 |
多种子类具有多种形态,由父类统一管理 |
父类指针具有多种形态 |