类中有三种成员函数:static成员函数、nonstatic成员函数、virtual成员函数。
成员函数命名:类中的成员函数允许函数重载,重载的机制就是对函数名+参数名进行编码获得唯一名称
1.static成员函数
static成员函数主要特性就是它没有this指针。下面的特性主要就是源于他的主要特性:
·static成员函数只能存取static数据成员
·它不能够被声明为const、virtual或voliate
·它不需要经由class 对象进行调用
如果取一个static成员函数的地址,获得的将是其在内存中的实际地址
例如:static int foo(); int (*p)()=&A::foo();
调用static成员函数和调用nonstatic成员函数效率是一样的
2.nonstatic成员函数
虽然取nonstatic成员函数的地址,会得到其在内存中的实际地址,并且是存储在类对象外部的,但是调用nonstatic成员函数必须通过类对象调用,就是通过this指针
因为nonstatic成员函数可以直接引用类的数据成员
编译器将this指针传作为参数传递进nonstatic成员函数,通过this指针存取数据成员
编译器将nonstatic成员函数转化为了非成员函数,所以调用nonstatic成员函数和非成员函数效率上没有区别
3.virtual成员函数
1.单一继承
单一继承情况下子类会继承父类的vptr和虚函数表,如果子类定义了不同的虚函数,那么将此虚函数添加在虚函数表的底部,如果对父类虚函数进行了重写,那么在原有虚函数的位置上覆盖指向新的函数地址
内存布局如下图
2.多重继承
多重继承牵涉到this指针的调整等问题,也就是第二个以及以后的父类地址问题
如果用指向第二或或后继的父类的指针来调用子类的虚函数,该调用操作必须调整this指针,使其指向子类的开头地址。
如果用指向子类的地址调用第二或后继父类的虚函数,同样需要调整this指针
对于多重继承来说,编译器会实现多个虚函数表,其中第一个基类的虚函数表为主要实体,其余的为次要实体
凡是继承类中存在的虚函数,都会在主虚函数表中出现,对于没有修改的虚函数,其实际地址存放位置仍然在原父类的虚表中,调用的时候需要进行this指针调整
内存布局如下图
上图中带有*的slot表示需要进行this指针的调整
如:通过指向第二个base类指针,调用derived类中的虚函数
或者通过derived类的指针,调用第二个base类中的虚函数,都需要进行this指针的调整
3. 虚拟继承
虚拟继承的子类生成一个vptr和一个虚函数表,虚函数表中存放虚基类对象的offset,