C和C++的不同
- 基本数据类型的不同
bool、字符串、void* - 复合数据类型的不同
结构、联合可以有成员函数,有隐藏的四大成员函数(构造、析构、拷贝构造、赋值),可以管理访问权限。 - 枚举检查更严格
枚举变量不能被整型数据赋值。 - 类型限定符不同
const不会主动读取被保护的值,默认只使用初始化的值,可以定义常函数。
static修饰符合类型的成员变量和成员函数。 - 强制类型转换的方式不同
(类型)数据
xxx_cast <目标类型>(数据) - 堆内存的管理方式不同
malloc 函数
new 语句 - 函数的不同
可以重名
可以有默认参数
可以内联 - 增加了引用的机制
指针与引用的区别 - 增加了对象
抽象、封装、继承、多态 - 增加了模板
- 增加了异常处理
- 增加了命名空间
- 输入输出语句不同
printf/scanf函数 根据点符设置数据的类型
cin/cout类对象 自动识别类型
一、new/delete和malloc/free
new/delete | malloc/free |
---|---|
直接使用 | 需要加头文件 |
自动计算字节数 | 手动计算 |
(返回)有类型的地址 | void*类型的地址 |
可以自动调用构造、析构函数 | 无法调用构造、析构函数 |
出错时抛异常 | 返回NULL |
相同点:
- 收拾用来管理内存的
- 都可以释放空指针
- 都不能重复释放
(注意:delete可以重复释放空指针)
二、什么是函数重载,C++是如何实现函数重载机制的?
同一个作用域,函数名相同、参数不同构造重载关系。
C++编译器会对函数的名字进行改名,会把参数的类型信息,添加到函数名的末尾,具有重载函数的同名函数最终的函数名是不同的。
extern “C”{
告诉编译器编译时不要对函数进行换名,以C语言的函数命名机制编译,使用它可以使用C编译器编译出的目标文件、库文件。
}
三、指针与引用的区别
指针 | 引用 |
---|---|
数据类型 | 命名机制 |
定义指针变量 | 取别名 |
占用4字节 | 不占用内存 |
可以不初始化 | 必须初始化 |
有空指针 | 没有空引用 |
方便配合堆内存使用 | 变量传参 |
可以定义指针数组 | 不能定义引用数组,但可以定义数组引用 |
可以定义二级指针 | 不能定义二级引用 |
有野指针 | 悬空引用 |
相同点:
- 跨函数共享变量
- 提高函数的传参效率
- 都需要const保护
总结:引用比指针的效率高、安全,但无法方便配合堆内存使用,所以提高函数的传参效率、跨函数共享变量时使用引用,访问堆内存使用指针。
四、对象的创建和释放过程
-
1、创建
-
1、分配内存
2、根据继承表顺序调用父类构造(与初始化列表无关)
3、根据成员定义顺序调用成员的构造函数
4、执行自己的构造函数
2、释放
-
1、执行自己的析构函数
2、根据成员的定义顺序,逆序调用成员的析构函数
3、根据继承表顺序,逆序调用父类的析构函数
4、释放对象的内存
五、什么是多态
指令的多种形态,相同的命令会根据环境、参数的变量自动执行相应的功能。
-
编译时多态:
-
1、函数重载
2、运算符重载
3、函数模板、类型模板
运行时多态:
- 基于类继承+虚函数+函数覆盖,通过父类型指针或引用调用虚函数,此时既可能调用父类函数,也可能调用子类函数。
六、类多态的实现机制
类中一旦定义了虚函数,他就会多了个隐藏的成员,虚函数指针,他指向一张虚函数表,该表中记录类中所有的虚函数。
当有虚函数类被继承时,虚函数指针也会被继承,如果他的成员函数与虚函数表中的函数名相同且参数、返回值符合要求,该成员函数的地址就会替换虚函数表中的地址,这样就完成了函数覆盖。
当通过父类指针、引用调用虚函数时,他会根据实际的类对象调用虚函数表中的函数,父类对象调用未覆盖的,子类对象调用覆盖后的。
七、智能指针
C++中的智能指针就是重载的*、->运算符的类对象。
- 与智能指针相比,普通指针的缺点?
容易忘记使用delete语句释放他所指向的堆内存导致内存泄漏。 - 智能指针的优点:
由于他的本质是类对象,离开智能指针所在的作用域时,会自动调用对象的析构函数,而在析构函数中会自动释放它所指向的堆内存,达到自动释放堆内存的效果。 - 智能指针的缺点:
1、不能使用多个智能指针指向一块堆内存
2、出了作用域智能指针就不能使用,他的释放时间不可控。
3、不能使用指针指向数组型对象
4、不能作为函数参数,也不能放入容器中
八、vector与list的区别
- vector和数组类似,拥有一段连续的内存空间,并且起始地址不变。vector和数组类似,拥有一段连续的内存空间,并且起始地址不变。
因此,它能够高效地进行随机存取,时间复杂度是O(1)。
但是,因为其内存空间是连续的,所以在进行插入和删除操作时,会造成内存块的拷贝,因此时间复杂度为O(n)。
另外,当数组内存空间不够时,会重新申请一块内动空间并进行内存拷贝。 - list是由双向链表实现的,因此内存空间是不连续的。
其只能通过指针访问数据,所以list的随机存取效率很低,时间复杂度为O(n)。
不过由于链表自身的特点,能够进行高效的插入和删除。 - vector和list对于迭代器的支持不同。
相同点在于,vector< int >::iterator和list< int >::iterator都重载了 “++ ”操作。
而不同点在于,在vector中,iterator支持 ”+“、”+=“,”<"等操作。而list中则不支持。
版权声明:《vector与list的区别》为CSDN博主「WhiteJunior」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/lym940928/article/details/83063699