Day02
1. 请你说说 delete 和 free 的区别
- delete是操作符,而free是函数
- delete用于释放new分配的空间,free用于释放malloc分配的空间
- free不会调用对象的析构函数,而delete会调用对象的析构函数
- 调用free之前需要检查要释放的指针是否为NULL,使用delete释放内存不需要检查
2. 简述一下什么是面向对象
- 封装:将客观事物进行抽象,将其属性和方法合成为一个类,类封装了成员变量和成员函数,同时又实现对属性和方法的权限控制,降低了外界的耦合度
- 继承:子类继承父类的各种属性和方法,同时子类还可以再父类的基础上重新定义和扩展父类的属性和方法,使其具有不同的功能,继承提高了代码的复用性和可维护性,以及扩展性
- 多态:统一调用语句在父类和子类间使用时具有不同的表现形式,可以使用同一段代码处理不同类型的对象,提高代码的复用性
3. 简述一下 C++ 的重载和重写
- 重载:同一个类中或多个函数之间,函数名相同,函数参数的个数或函数参数类型不同的函数称为函数的重载,函数重载是水平关系
- 重写:子类继承于父类,并重写父类的虚函数,要求函数名、参数类型以及参数个数都相同,仅函数体不同,称为函数的重写。子类对父类的重写一般在函数后面加上override关键字,以此来表明此函数是重写父类的函数,在函数调用时,如果是基类指针指向派生类对象,则调用的是派生类的虚函数,因此,一般基类的虚构函数需要设置为虚函数,用以成功释放子类内存资源,重写是动态多态的体现,重载是静态多态的体现
4. 简述一下浅拷贝和深拷贝
- 深拷贝和浅拷贝最根本的区别在于是否真正获取一个对象的复制实例,而不是一个引用。深拷贝和浅拷贝一般在拷贝构造函数和赋值运算符重载函数中涉及到
- 浅拷贝又称为值拷贝,将源对象的值拷贝到目标对象中,如果对象中有某个成员是指针类型数据,并且是在堆区创建,则使用浅拷贝仅仅是拷贝这个指针变量的值,也就是在目标对象中该指针类型数据和源对象中的指针类型数据指向的是同一块堆空间。这样会带来一个问题,就是在析构函数中释放该堆区的数据时,会被调用多次。默认的拷贝构造函数和默认的赋值运算符重载函数都是浅拷贝
- 深拷贝在拷贝的时候先开辟出和源对象大小一样的空间,然后将源对象里的内容拷贝新空间,这样指针变量就指向了不同的内存位置,但是里面的内容是一样的,这样就达到了不出问题拷贝的目的,两个对象先后调用析构函数,分别释放自己指针成员所指向的内存;深拷贝情况下,不会出现重复释放同一块内存的错误
5. 简述一下 C++ 中的多态
- 在面向对象中,多态是指通过基类的指针或者引用,在运行时动态调用实际绑定对象函数的行为,与之对应的编译时绑定函数称为静态绑定。所以多态分为静态多态和动态多态。
- 静态多态:是编译器在编译期间完成的,编译器会根据实参类型来选择调用合适的函数,如果有合适的函数就调用,没有就会报错。静态多态有函数重载,运算符重载,泛型编程等
- 动态多态:动态多态是在程序运行时根据基类的引用(指针)指向的对象来确定自己具体该调用哪一个类的虚函数。当父类指针指向父类,就调用父类的虚函数,当父类指针指向子类对象时,就调用子类中定义的虚函数
- 动态多态的条件:要有继承关系,要有方法重写,要有父类指针指向子类对象
- 动态多态的实现原理:当类中声明虚函数时,编译器会在类中生成一个虚函数表,虚函数表是一个存储类虚函数指针的数据结构,虚函数表是由编译器自动生成并维护的。virtual成员函数会被编译器放入虚函数表中,存在虚函数时,每个对象都有一个指向虚函数表的指针(vptr指针)。在多态调用时,vptr指针就会根据这个对象在对应类的虚函数表中查找被调用的函数,从而找到函数的入口地址