准备面试
1、重载、覆盖、隐藏
重载:在同一个作用域中,函数名字相同,参数列表不一样(函数的返回类型不能区分重载);
覆盖:也叫重写override,在基类与派生类中,都是虚函数,派生类中与基类中该虚函数除了函数体不一样,其他都一样。例子:
C1 c3 = new C2();
Console.WriteLine(c3.GetName());//输出“xumingxiang”子类的函数
隐藏:在基类与派生类中,派生类中屏蔽了基类的同名函数。(参数列表不一样,与是否虚函数无关)
2、左值引用与右值引用
左值引用只能绑定到左值,不能绑定到右值,const左值引用即可绑定左值也可绑定到右值。
C++11提出了右值引用,&&
int &&rref = 10;//只能绑定右值,不能绑定左值
= a;//xx
移动构造函数
string(string && rhs) //优先选择右值引用这个构造函数,而不是const string &那个
:_pstr(rhs._pstr)
{} //不写就没有,不是自动生成的(移动构造函数)。
3. 俩分钟写完单例对象
#include <iostream> using namespace std; class Singleton { public: static Singleton * getInstance() { if(nullptr == _pInstance){ _pInstance = new Singleton(); } return _pInstance; } static void destroy() { if(_pInstance){ delete _pInstance; _pInstance = nullptr; } } private: Singleton() :_data(100) {} ~Singleton(){cout<<"~Singleton()"<<endl;} private: int _data; static Singleton *_pInstance; }; Singleton * Singleton::_pInstance = nullptr;//类外初始化 int main() { Singleton *ps1 = Singleton::getInstance(); Singleton *ps2 = Singleton::getInstance(); cout<<"ps1:"<<ps1<<endl; cout<<"ps2:"<<ps2<<endl; Singleton::destroy(); return 0; }
4、多态、静态多态、动态多态
多态:同一指令,针对不同对象,产生不同行为;
静态多态:函数重载,运算符重载,模板(发生的时机是在编译时)
动态多态:发生的时机是运行时,体现形式:虚函数。
5、std::string 的底层实现 Eager cope(无特殊处理)、cope-on-write、sso(short string optimization)
无特殊处理(eager copy),采用类似std::vector的三指针数据结构。现在很少采用这种方式。
cow写时复制:多线程不安全,源码实现中会用原子操作
如果我们的复制操作时,进行的是浅拷贝,只有当需要修改字符串内容时,才真正执行拷贝操作,再去进行修改。只有当没有指针指向该空间时,才需要释放,因此引入一个引用计数。
sso:字符串长度<=15时,才与字符串对象存于同一空间。sso的实现对于短字符串来说,是有优化的,因为字符串内容并不长,如果是存储在栈上,效果更加。栈上开空间比在堆上开空间要快得多,不需要查找,直接偏移函数栈空间的指针就行了。
针对不同的应用负载选用不同的 string,对于短字符串,用 SSO string;对于中等长度的字符串,用 eager copy;对于长字符串,用 COW。
6、