栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

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

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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

文章目录
    • C++对象模型
    • 需要多少内存才能够表现一个 class object?
    • 指针类型
    • 加上多态后
    • C++有三种方式支持多态

C++对象模型

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

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

这个模型的主要优点在于它的空间和存取时间的效率;主要缺点则是,如果应用程序代码本身未曾改变,但所用到的 class objects的 nonstatic 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 ;
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))

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/989714.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号