《深度探索C++对象模型》阅读笔记 第一章 关于对象

C++对象模型

C++类包含两种数据成员:静态数据成员和非静态数据成员;同时包含成员函数,静态函数和虚函数三种成员函数
在此模型中,Nonstatic data members被配置于每一个 class object 之内,static data members则被存放在所有的 class object 之外. staticnonstatic function members也被放在所有的class object 之外. Virtual functions 则由虚表机制实现,class 里保存着一个指向虚表的指针,虚表中存放着指向虚函数的函数指针。
在这里插入图片描述

每一个class所关联的type_info object(用以支持 runtime type identification,RTTI)也经由 virtual table 被指出来,通常是放在表格的第一个slot处。

这个模型的主要优点在于它的空间和存取时间的效率;主要缺点则是,如果应用程序代码本身未曾改变,但所用到的 class objectsnonstatic data members有所修改(可能是增加、移除或更改),那么那些应用程序代码同样得重新编译,关于这点,前述的双表格模型就提供了较大的弹性,因为它多提供了一层间接性,不过它也因此付出空间和执行效率两方面的代价就是了。

需要多少内存才能够表现一个 class object?

  • 所有非静态数据成员的大小。
  • 由内存对齐而填补的内存大小。
  • 为了支持virtual有内部产生的额外负担。
    如下类:
class ZooAnimal {  
    public:  
    ZooAnimal();  
    virtual ~ZooAnimal();  
    virtual void rotate();  
    protected:  
    int loc;  
    String name;  
};

在32位计算机上所占内存为16字节:int四字节,String8字节(一个表示长度的整形,一个指向字符串的指针),以及一个指向虚函数表的指针vptr。对于继承类则为基类的内存大小加上本身数据成员的大小。

指针类型

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

  • 一个指向地址1000的整数指针,在32位机器上,将涵盖地址空间1000~1003(译注:因为32位机器上的整数是4-bytes)
  • 一个指向地址1000而类型为void的指针,将涵盖怎样的地址空间呢?是的,我们不知道!这就是为什么一个类型为void的指针只能够含有一个地址,而不能够通过它操作所指之object的缘故。

所以,转型(cast)其实是一种编译器指令。大部分情况下它并不改变一个指针所含的真正地址,它只影响“被指出之内存的大小和其内容”的解释方式。

加上多态后

好,假设我们的 Bear object放在地址1000处,一个Bear指针和一个ZooAnimal 指针有什么不同?

Bear b;
ZooAnimal *pz = &b;    //Bear继承自ZooAnimal
Bear *pb = &b;

它们每个都指向Bear object的第一个byte.其间的差别是,pb所涵盖的地址包含整个 Bear object,而pz所涵盖的地址只包含 Bear object中的 ZooAnimal subobject.
自己编写的例子

#include <iostream>;
using namespace std;
class base {
public:
    virtual void o()
    {
        cout << "base" << endl;
    }
};
class A : public base {
public:
    int a = 1;
    virtual void o()
    {
        cout << "a" << endl;
    }
};
class B : public base {
public:
    virtual void o()
    {
        cout << "b" << endl;
    }
};
int main()
{
    A se;
    base& b = se;
    b.o();
    cout << b.a;	//此处报错: 类 "base" 没有成员 "a"
}

所以多态的应用重点在于虚函数上,因为只要有虚函数的类,就有虚指针。

C++有三种方式支持多态

1、经由一组隐式的转化操作,比如将派生类指针转化为指向其基类的指针 shape *ps =new circle();

2、经由virtual function机制 ps->rotate()

3、经由dynamic_cast 和typeid运算符

if(circle _pc = dynamic_cast (ps))

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值