1. new/delete 与 malloc/free的区别
- malloc/free是标准库函数,new/delete是C++运算符。运算符是语言本身的特性,有固定的语义,由编译器解释语义。库函数是依赖于库的,一定程度上独立于语言,编译器不关心库函数的作用。
- delete会调用对象的析构函数, free只会释放内存,new调用构造函数。malloc/free是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于malloc/free。
2. 多态,虚函数,纯虚函数
- 多态:对于不同对象接收相同消息时产生不同的动作。C++的多态性具体体现在运行和编译两个方面:在程序编译时多态性体现在函数和运算符的重载上,在程序运行时的多态性通过继承和虚函数来体现。
- 虚函数:在基类中冠以关键字 virtual 的成员函数。它提供了一种接口界面。允许在派生类中对基类的虚函数重新定义。
- 纯虚函数:在基类中为其派生类保留一个函数的名字,以便派生类根据需要对它进行定义。作为接口而存在纯虚函数不具备函数的功能,一般不能直接被调用。
3. 堆与栈的区别
栈,就是那些由编译器在需要的时候分配,在不需要的时候自动清除的变量的存储区。里面的变量通常是局部变量、函数参数等。
堆,就是那些由 new 分配的内存块,他们的释放编译器不去管,由我们的应用程序去控制,一般一个 new 就要对应一个 delete。如果程序员没有释放掉,那么在程序结束后,操作系统会自动回收。
4. 数组与指针的区别
(1)数组一旦声明,我们就不能再给他赋值,但是可以给指针赋值
1 int main(){
2 char s[]="123";
3 char p[]="123";
4 char *t=NULL;
5 s=t;
6 s=p;
7 }
程序会在编译时报。5、6行都错,因为数组s不能作为左值被赋值。
(2)用指针定义字符串时,指针所指的字符串会被理解为常量字符串,不能修改。数组定义的字符串则可以修改
void swap(char &i,char &j){
char t=i;i=j;j=t;
}
int main(){
char *s="1234";
char s1[]="1234";
swap(s1[0],s1[2]);
printf("%s\n",s1);
swap(s[0],s[2]);
printf("%s\n",s);
}
例子中用 swap 对指针进行修改,比较 s 和 s1 的不同。
结果:s1 的结果能够正确输出,但是程序会在 swap 交换 s 的元素时,在 i=j 这一句挂掉。原因即为上面所说,指针声明的字符串是常量的。
报错阶段:程序运行时,直接挂掉。
(3)用sizeof运算符可以计算数组变量的数组大小,但指针指向数组时,只能计算出指针本身大小(单位:字节)
int main(){
char *s="1234567890";
char s1[]="1234567890";
printf("s:%d s1:%d char:%d",sizeof(s),sizeof(s1),sizeof(char));
}
运行结果:s:8 s1:11 char:1
注意,字符串的结束符’\0’也被 sizeof 计算在内,因此字符串类型比内容长1。
5. 指针与引用的区别
- 引用是变量的一个别名,内部实现是只读指针;
- 引用只能在初始化时被赋值,其他时候值不能被改变,指针的值可以在任何时候被改变;
- 引用不能为NULL,指针可以为NULL;
- “sizeof 引用” = 指向变量的大小 , “sizeof 指针”= 指针本身的大小;
- 指针允许多级操作,如**p,引用不行。
6. C与C++的区别
相对于C,C++多了重载、内联函数、异常处理等,扩展了面向对象的设计内容:类、继承、虚函数、模板。
7. 关键字 static 的作用
- 函数体内 static 变量的作用范围为该函数体,该变量的内存只被分配一次,因此其值在下次调用时仍维持上次的值;
- 在模块内的 static 全局变量可以被模块内所有函数访问,但不能被模块外其他函数访问;
- 在类的static 成员变量属于整个类所拥有,对类的所以对象只有一份拷贝;
- 隐藏性,当同时编译多个文件时,所有未加static前缀的全局变量和函数都具有全局可见性。
8. 封装、继承与多态的解释
- 封装是实现面向对象程序设计的第一步,封装就是将数据或函数等集合在类中。封装的意义在于保护或者防止代码(数据)被我们无意中破坏;
- 继承主要实现重用代码,节省开发时间。子类可以继承父类的一些东西;
- 同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果。
9. C++ 中 struct 与 class 区别
最大的区别:class 中的成员默认是 private,而 struct 的成员默认为 public。
10. 野指针
野指针不是空指针,是一个指向垃圾内存的指针。
其形成的原因有:
(1)指针变量在创建时没有被初始化,其缺省值为随机;
(2)指针被 free 或 delete 掉后没有设置为 NULL,只是把指针所指向的内存释放掉,并没有把指针本身清理掉;
(3)指针操作超越了变量的作用范围,比如指针执行 ++ 操作越界。
11. 深拷贝与浅拷贝
浅拷贝:增加了一个指针,指向原来已经存在的内存。在多个对象指向一块空间的时候,释放一个空间会导致其他对象所使用的空间也被释放了,再次释放便会出现错误。
深拷贝:增加了一个指针,并新开辟了一块空间,让指针指向这块新开辟的空间。
12. 方法重载与重写区别
重载:同一个类中的两个或两个以上的方法,拥有相同的方法名,但是参数却不相同,方法体也不相同;
重写:子类的方法覆盖父类的方法,要求返回值、方法名和参数都相同。