2)每个对象被添加一个指针,指向相关的virtual table,通常这个指针被称为vptr(虚函数表指针)vptr的设定和重置由每一个类的构造函数,析构函数和复制构造函数自动完成。每个类所关联的type_info信息(用以支持rtti)也由virtual table 指出。通常放在表格的第一个slot处。
2.5.2含静态变量、虚函数的类的空间计算
sizeof应用在类和结构的处理情况是相同的。但是在类中的静态成员不对结构或类的大小产生影响。
2.5.3虚基类表指针
c++支持单一和多重继承。
class iostream:public istream,public ostream{...};
继承关系也可以指定为虚拟(virtual 共享的意思)
class istream :virtual public ios{...};
class ostream :virtual public ios{...}; //菱形继承
在虚拟继承中,基类不管在继承串链中被派生多少次,永远只会存在一个实体。
在虚拟继承基类的之类中,子类会增加某种形式的指针,或者指向虚基类子对象,或者指向一个相关的表格,表格中存放的不是虚基类子对象的地址,就是其偏移量。此指针叫bptr.
2.5.4 虚拟继承时构造函数的书写
从A类直接虚拟派生(B和C)和间接派生(D)的类中,其构造函数的初始化列表中都要列出对基类A构造函数的调用。这种机制保障不管有多少层继承,虚基类的构造函数必须且只能被调用一次。
若在初始化列表中没有显式调用虚基类的构造函数,则将调用虚基类的默认构造函数。若虚基类没有定义默认构造函数,则编译错误。
2.5.5虚函数
在基类中不能给出虚函数有意义的实现,而把它声明为纯虚函数,他的实现留给基类的派生类去做。
a.两种常见的抽象类
凡是有纯虚函数 的类叫抽象类(抽象接口),这种类不能声明对象,只是作为基类为派生类服务。除非在派生类中完全实现基类中的所有纯虚函数,否则,派生类也是抽象类,不能实例化对象。
只定义了protected型构造函数的类也是抽象类。对于一个类,如果只定义了protected构造函数而没有提供public构造函数,无论是外部还是派生类中都不能创建该类的对象,但能派生出新类,这种能派生出新类,但不能创建自己对象的类叫另外一种形式的抽象类。
3.运行时类型识别与显示转换
3.1 typeid
c++通过下面两种操作符提供RTTI
1)typeid 操作符,返回指针或引用所指对象的实际类型。
2)dynamic_cast操作符,将基类类型的指针或引用安全的转换为派生类型的指针或引用。
只有当typeid的操作数是带虚函数的类类型的对象时,才返回动态类型信息。
3.2 显式转换
c++中的显式转换也称强制类型转换。包括static_cast、dynamic_cast、 const_cas、 reinterpret_cast。
在引用命名的强制类型转换操作符之前,显式强制类型转换用圆括号将类型括起来实现。
1) reinterpret_cast
int *ip;
char *pc=(char*) ip;
效果与reinterpret_cast相同。
int *ip;
char *pc=reinterpret_cast<char*> ip;
2) const_cast
除了添加和删除const特性,用const_cast符执行其他任何类型转换都会引起编译错误。
3)static_cast
编译器隐式执行的任何类型转换都可以由static_cast显式完成。