深度探索C++对象模型 第一章

来源:互联网 发布:淘宝企业店铺要交税吗 编辑:程序博客网 时间:2024/05/21 17:43

第一章 关于对象


C++对象模型

class Point{

public:

Point(float xval);

virtual ~Point();


float x() const;

static int PointCount();


protected:

virtual ostream& print(ostream &os) const;


float x;

static int _point_count;

};


简单对象模型:

每一个成员函数和成员数据都有一个slot。

2017-9-13 下午9.09 拍摄的照片.jpg




表格驱动对象模型:

object里面只存两个指针。

2017-9-13 下午9.11 拍摄的照片.jpg




C++对象模型:


object里面有:成员变量、虚指针


虚指针vptr指着虚表,虚表vtbl里面是指针(指着虚函数)。


而其他的静态成员或是非虚成员函数都在其他地方存储。


优点:空间和存取时间的效率

缺点:如果是非静态成员变量有所改变,那么应用程序代码就要重新编译。


2017-9-13 下午9.11 拍摄的照片 #2.jpg





虚继承:以iostream举例


2017-9-13 下午9.25 拍摄的照片.jpg

base 不管在继承串中派生多少次,永远只会有一个实例。



缺点:由于间接性而导致空间和存取时间上的额外负担。

优点:每一个类都有一个bptr指针,与base classes大小个数无关。

不用改变类本身,就能通过指针放大、缩小或更改 base class table。

2017-9-13 下午9.25 拍摄的照片 #2.jpg




X foobar()

{

X xx;

X *px = new x;

//foo() 是一个virtual function

xx.foo();

px->foo();


delete px;

return xx;

}


2017-9-13 下午9.26 拍摄的照片.jpg



1.3 对象的差异




已知Book 继承自 Li


Li thing1;

Book book;

thing1 = book;   //向上转型,会发生裁剪

thing1.check_in(); //调用Li::check_in()


Li &thing2 = book; //相当于指针

thing2.check_in(); //Book::check_in() 只有通过指针或者引用才构成多态



指针的类型:


指针类型会教导编译器如何解释某个特定地址中的内存容量及大小。


所以说cast转换是一种编译器指令。大部分情况下不会改变指针所含的真正地址,只影响“被指地址中的内存容量及大小”的解释方式。



class ZooAnimal{

public:

ZooAnimal();

virtual ~ZooAnimal();

//...

virtual void rotate();


protected:

int loc;

string name;

};


ZooAnimal za("Zoey");

ZooAnimal *pza = &za;


2017-9-13 下午9.57 拍摄的照片.jpg



加上多态之后:

class Bear : public ZooAnimal{

public:

Bear();

~Bear();

//...

void rotate();

virtual void dance();

protected:

enum Dance{...}

Dance dances_known;

int cell_block;

};


Bear b("Yogi");

Bear *pb = &b;

Bear &rb = *pb;


2017-9-13 下午9.57 拍摄的照片 #2.jpg




Bear b;

ZooAnimal *pz = &b;

Bear *pb = &b;


pz->cell_block;//不合法,pz所涵盖的地址只包含Bear object中ZooAnimal的部分。

//如果想用,只能转换指针类型



pz->rotate(); //虚函数,在每一个执行点,pz所指的对象类型可以决定rotate()调用的实例。






ZooAnimal <----Bear <----- Panda


2017-9-13 下午9.58 拍摄的照片.jpg