c++对象模型的设计:nonstatic的data members被放置于每一个class之内,static的data members则被放置于class之外,static和nonstatic的function被放置于class之外。virtual function以下面两个步骤支持:
- 每个class产生一个virtual table(vtbl),里面存放指向每个virtual function的指针。
- 每一个class对象有一个指针vptr,指向相关的vtbl,vptr的设定和重置由每个class的构造函数、析构函数和copy assignment运算符自动完成。vtbl的第一个slot通常放的是这个class的type_info object指针,用以支持runtime type identification,RTTI
static变量存放于全局变量区(.data),是为符合static语义,其需要在类外进行初始化,分配内存,因为它的生命周期是全局,而class对象的生命周期在它被定义之后才开始。
c++中class和struct的差异:struct可以干class的所有事情,只是struct的默认成员访问权限为public,class的默认成员访问权限为private;struct默认是公有继承,class默认是私有继承;当struct和class中没有构造函数且成员变量(无需成员函数)全为public时,可以用{}进行初始化。
struct适合看成是一个数据的集合体;class适合看成一个对象。
c++以下列方法支持多态:
1. 经由一组隐式的转化操作,例如将派生类指针转化为一个指向其基类的指针:
Shape *ps = new Circle();
2. 经由virtual function机制:
ps -> rotate();
3.经由dynamic_cast和typeid运算符
if(Circle *pc = dynamic_cast<Circle*>(ps)) ...
typeid本质上即是通过虚函数表的第一个slot内的指针所指向的type_info object来判断是哪种class
多态的主要用途是经由一个共同的接口来影响类型的封装,这个接口通常定义在基类中,并在不同的派生类中有不同的实现。通过virtual function机制在运行时才确定到底调用哪个函数实例。
void rotate(X datum, const X *pointer, const X& reference) { //下面这个操作总是调用X::rotate(),因为datum的类型已经确定,不走虚函数表的方式; datum.rotate(); //下面这两个操作必须在运行期才能知道调用的是那个rotate()实例 (*pointer).rotate(); reference.rotate(); } main() { Z z; //Z是X的一个子类型 rotate(z, &z, z); return 0; }
不同类型指针的差别:只在其所寻址出来的object类型不同,“指针类型”会教导编译器如何解释某个特定地址的内存内容及大小。一个类型为void*的指针只能够持有一个地址,而不能通过它操作所指的object。
Bear b; ZooAnimal *pz = &b; Bear *pb = &b;
pz和pb都指向Bear object的第一个byte,其间差别:pb所涵盖的地址包含整个Bear object,而pz所涵盖的地址只包含Bear object中的zooAnimal部分。
Bear b; ZooAnimal za = b; //引起切割,事实上会调用拷贝构造函数,设定正确的vptr za.rotate(); //调用ZooAnimal::rotate(),在编译器就已经确定
一个指针或者引用之所以支持多态,是因为它们不引发内存中与类型相关的改变,而只改变它们所指向内存的“大小和内容解释方式”。
原文地址:https://www.cnblogs.com/senshaw/p/10944439.html