静态:
(1)类静态数据成员在编译时创建并初始化,属于类,不属于某个对象,为所有对象所共享,包括该类派生类的对象,可以通过类名or对象访问。
(2)static成员变量,可以实现同类对象间的信息共享。存储在数据段(data-rw){全局变量也是存储在data区},故而计算类大小时,不将其计算在内。
(3) static成员可以产业能够为成员函数的可选参数{可选参数必须放在参数表的最右边},普通数据成员则不可以。
1 void fun(int a,int b,int c=10);2 fun(1,2); //a=1,b=2,c=103 4 void fun(int a,int b=10,int c);5 fun(1,2); //a=1,b=? c=?
class base{public: static int static_var; int var; void foo1(int i=staitc_var);//正确 void foo2(int i=var);//错误}
(4)数据成员的类型和初始化方式:/cite https://www.nowcoder.com/questionTerminal/b73db04e98174120b50b5478839b3f8f?orderByHotValue=1&mutiTagIds=569&page=1&onlyReference=false
static成员 | 初始化在类外,且不加static修饰 |
const成员 | 只能在构造函数后的初始化列表中初始化 |
const static成员 | 类只有唯一一份拷贝,且数值不能改变。因此,可以在类中声明处初始化,也可以像static在类外初始化 |
(5)静态成员函数的意义,是在于管理静态数据成员,完成对静态数据成员的封装。因为非静态成员函数,在调用时this指针会被当做参数传入,静态函数成员属于类,不属于对象,无this指针,所以静态函数成员只能访问静态数据成员。
(6)静态成员函数不可以同时声明为virtual,const,volatile函数。
/cite http://www.jianshu.com/p/a3303c9ba748
/cite http://www.cnblogs.com/Myhsg/archive/2009/07/31/1535650.html
同步IO和异步IO:
(1)同步IO,发出一个功能调用时,在没有得到结果之前,该调用就不返回。
(2)异步IO,当一个异步调用发出后,通过状态、通知、回调函数来通知调用者。
IOCP:
(1)IOCP是一个异步I/O的API,可以高效地将I/O事件通知给应用程序。
C/C++内存的申请释放:
(1)malloc、free无法对非内部类型的对象自动执行构造函数、析构函数。
(2)macllo、free是库函数,不是运算符,所以不在编译器控制权限之内。new、delete不是库函数,是运算符,所以拥有执行构造函数、析构函数的权限。
(3)new出来的指针直接带类型信息,malloc返回的是void指针。
指针和引用:
(1)指针是一个变量,引用是一个别名。
(2)引用必须在定义的时候初始化,之后不能改变。
(3)引用不能为空,指针可以为空。
(4)sizeof(指针)为指针本身的大小,sizeof(引用)所指向对象的大小。
(5)不存在多级引用,引用不需要分配内存区域。
多态:
通过虚函数,在子类中通过重写的方式实现多态,实现根据对象的实际类型来调用相应的函数。
(1)存在虚函数的类都有一个一维的虚函数表,类的对象有一个指向虚函数表的虚指针。
(2)抽象类是至少包括至少一个纯虚函数的类。
多态的实现原理:
(1)早期绑定,静态绑定:编译器在编译的时候,需要确定每个对象调用(非虚函数)的地址。
(2)假设存在父类P,父类对指针*pf。子类C,子类对象c。子类和父类具有同名函数say()。当指针pf指向对象c时,通过指针调用say(),会调用父类中的函数。
class P{public: void say() { std::cout<<"I'm father"; }}class C:public P{ void say() { std::cout<<"I'm children"; }}void main(){ C c; P *pf=&c; pf->say();}
多态实现机制
理解多态首先要理解类对象的内存模型。
子类的对象内存模型是:父类的对象所占内存+子类的对象所占内存,所以当创建子类对象的时候,首先回去调用父类的构造函数,构造出父类的对象后,再调用子类的构造函数完成自身的构造。当将子类对象转换父类对象时,基于安全考虑,编译器会将该对象认为是子类对象模型的上半部分,也就是父类对象。所以使用类型转换后的对象指针调用函数的时候,会调用父类对象的函数。这些都是在编译期间决定的,为了达到对象和函数一一对应的目的,需要使用动态绑定,也就是使用多态。在基类中函数使用virtual关键字,此时子类会自动的在其同名函数上也加上,当然也可以手动添加virtual关键字。编译器会给有virtual关键字的类创建一个虚函数表(vtable){在构造函数中完成虚表的创建},里面以一维数组的形式记录了有virtual关键字的函数地址。为了定位vtable,编译器会给该类的每个对象提供了一个虚函数指针(vptr){在构造函数中完成虚指针的初始化},该指针指向了该对象所属类的vtable。
在程序运行时,会根据对象的类型初始化虚指针{不使用多态特性时,会根据指针/引用类型来调用相关函数},使其指向正确的vtable。虚表可以继承,即使子类中没有重写虚函数,子类仍然具有该函数的地址,如果子类重写了该虚函数,那么新地址会覆盖继承下来的虚表中记录的虚函数原地址,如果子类新增了虚函数,对应的虚函数表中会增加对应项。回顾上文所述的对象内存模型,对象会首先执行父类的构造函数,完成父类对象的构造和父类的虚表和虚指针后,再进行自身的构造。