1.C和C++有什么区别?
C++是面向对象的语言,而C是面向过程的语言;
C++引入new/delete 运算符,取代了C中的malloc/free 库函数;
C++引入引用的概念,而C中没有; C++引入类的概念,而C中没有; C++引入函数重载的特性,而C中没有
2.static关键字有什么作用?
修饰局部变量时,使得该变量在静态存储区分配内存;只能在首次函数调用中进行首次初始化,之后的函数调 用不再进行初始化;其生命周期与程序相同,但其作用域为局部作用域,并不能一直被访问;
修饰全局变量时,使得该变量在静态存储区分配内存;在声明该变量的整个文件中都是可见的,而在文件外是 不可见的;
修饰函数时,在声明该函数的整个文件中都是可见的,而在文件外是不可见的,从而可以在多人协作时避免同 名的函数冲突;
修饰成员变量时,所有的对象都只维持一份拷贝,可以实现不同对象间的数据共享;不需要实例化对象即可访 问;不能在类内部初始化,一般在类外部初始化,并且初始化时不加static ;
修饰成员函数时,该函数不接受this 指针,只能访问类的静态成员;不需要实例化对象即可访问。
3.#define和const有什么区别?
编译器处理方式不同: #define 宏是在预处理阶段展开,不能对宏定义进行调试,而const 常量是在编译阶段使用;
类型和安全检查不同: #define 宏没有类型,不做任何类型检查,仅仅是代码展开,可能产生边际效应等错
误,而const 常量有具体类型,在编译阶段会执行类型检查;
存储方式不同: #define 宏仅仅是代码展开,在多个地方进行字符串替换,不会分配内存,存储于程序的代码段中,而const 常量会分配内存,但只维持一份拷贝,存储于程序的数据段中。
定义域不同: #define 宏不受定义域限制,而const 常量只在定义域内有效。
4.对于一个频繁使用的短小函数,应该使用什么来实现?有什么优缺点?(内联函数)
应该使用inline 内联函数,即编译器将inline 内联函数内的代码替换到函数被调用的地方。优点:
在内联函数被调用的地方进行代码展开,省去函数调用的时间,从而提高程序运行效率;
相比于宏函数,内联函数在代码展开时,编译器会进行语法安全检查或数据类型转换,使用更加安全; 缺点:
代码膨胀,产生更多的开销;
如果内联函数内代码块的执行时间比调用时间长得多,那么效率的提升并没有那么大; 如果修改内联函数,那么所有调用该函数的代码文件都需要重新编译;
内联声明只是建议,是否内联由编译器决定,所以实际并不可控。
5.什么是智能指针?智能指针有什么作用?分为哪几种?各自有什么样的特点?
智能指针是一个RAII类模型,用于动态分配内存,其设计思想是将基本类型指针封装为(模板)类对象指针,并在 离开作用域时调用析构函数,使用delete 删除指针所指向的内存空间。
智能指针的作用是,能够处理内存泄漏问题和空悬指针问题。
分为auto_ptr 、 unique_ptr 、 shared_ptr 和weak_ptr 四种,各自的特点:
对于auto_ptr ,实现独占式拥有的概念,同一时间只能有一个智能指针可以指向该对象;但auto_ptr
在C++11中被摒弃,其主要问题在于:
对象所有权的转移,比如在函数传参过程中,对象所有权不会返还,从而存在潜在的内存崩溃问题; 不能指向数组,也不能作为STL容器的成员。
对于unique_ptr ,实现独占式拥有的概念,同一时间只能有一个智能指针可以指向该对象,因为无法进行拷贝构造和拷贝赋值,但是可以进行移动构造和移动赋值;
对于shared_ptr ,实现共享式拥有的概念,即多个智能指针可以指向相同的对象,该对象及相关资源会在其所指对象不再使用之后,自动释放与对象相关的资源;
对于weak_ptr ,解决shared_ptr 相互引用时,两个指针的引用计数永远不会下降为0,从而导致死锁问题。而weak_ptr 是对对象的一种弱引用,可以绑定到shared_ptr ,但不会增加对象的引用计数。
6、shared_ptr是如何实现的?
- 构造函数中计数初始化为1;
- 拷贝构造函数中计数值加1;
- 赋值运算符中,左边的对象引用计数减1,右边的对象引用计数加1;
- 析构函数中引用计数减1;
- 在赋值运算符和析构函数中,如果减1后为0,则调用delete 释放对象。