`
guoyiqi
  • 浏览: 1019110 次
社区版块
存档分类
最新评论

(转)c++对象内存分析5

 
阅读更多


前言前面4节我们已经完成了对4种C++对象布局的分析,本文试图覆盖更多的,常见的C++面向对象的概念。所以,最后2节将继续阐述2个主题:接口和抽象类以及构造函数、虚构函数和虚析构函数。
接口这里我准备只主要阐述接口,而不谈一般的抽象类。因为在C++中,是没有“接口”这种类型的,所有的接口事实上是定义为纯抽象类。所谓纯抽象类,就是没有成员变量,没有实现了的函数,只有纯虚函数的抽象类。我相信,理解了接口这种特殊的抽象类,再去理解一般的抽象类是很容易的。
来看一个例子,我们有接口IAnimal来表示一般的动物行为,代码如下:
class IAnimal
{
public:
virtual void Eat()=0;
virtual void Move()=0;
virtual void Sleep()=0;
};
这个接口在内存中的布局可以看作下图中的样子:


接口在内存中的布局可以看作一个虚函数指针指向一个虚函数表,虚函数表中的所有元素指向的地址为0,因为所有纯虚函数都没有被实现。
上面的描述只是为了大家理解方便,事实上这种说法是很不准确的。因为,一个接口是绝对不能被构造的,这一点很重要。接口中的纯虚函数都没有被实现,如果允许构造他们,那么在调用这些方法的时候,将造成非法访问异常。
我们的问题来了,既然接口不允许被构造,那么我们为什么经常看到各种接口类型的对象呢。很简单,这些接口类型的对象都是由从该接口继承的子类对象通过类型转换而来的。在子类中,我们需要实现接口的所有方法,否则,该子类仍是一个抽象类。下图中,我们描述了继承了IAnimal接口的Horse类的内存结构图,这个类还继承了IVehicle接口:

关于Horse类如果进行指针调整,怎么转换为IAnimal接口类型,并实现多态特性的,我们在前面的章节中不止一次涉及到,即使是接口,也没有什么不同,我们这里不打算再重复。
下面,我们要谈的是,为什么我们要使用接口呢? 由于本文主要研究的是对象的内存布局,所以,关于这个涉及设计模式的主题,我只准备简单的讲述,这个主题太大了,因此我只希望下面的描述能给你一些关于接口应用场景的灵感。我们经常听到关于接口的描述是“只要实现了某某接口,对象就能实现某某功能/流程”,或者“就能被某某方法/模块调用来实现某某功能/流程”。 我们来看下面的代码:
void AnimalHappyDay(IAnimal* animal)
{
animal->Eat();
animal->Move();
animal->Sleep();
}
类似的,我们要说,任何类只要实现了IAnimal接口,AnimalHappyDay函数就可以调用该类的对象,来实现动物快乐的一天!我们不用关心这个类是猫,狗还是独角兽,不用关心它是否还实现了其他的接口,不用关心它是直接实现IAnimal接口的,还是间接的。他们只有一个共同点,就是实现了IAnimal接口。那么,它就可以被AnimalHappyDay函数调用,Eat,Move,Sleep,来实现动物快乐的一天这个功能。
一个接口,应该是最小粒度的。所谓最小粒度,首先,它没有任何的实现,只是用来描述一种标准的调用规范,完全由子类去实现它。其次,它只包含实现流程需要的最小的方法集合,比如,我们在IAnimal接口中不应该加入Grow方法,因为AnimalHappyDay流程不需要该方法,如果我们加入Grow方法,所有继承IAnimal的类就不得不去实现它。应该把Grow方法放在其他接口中,比如ILIfe接口,这个接口中或许定义了Both,Dead方法,用来实现动物的生命周期,类作者可以选择是否要去实现该接口。

分享到:
评论

相关推荐

    C++对象内存模型.pdf

    本文将通过实验和分析来探索 C++ 对象内存模型,并讨论对象内存结构、简单类型相关数据、包含虚函数类的对象内存结构、继承下的多态性等问题。 1. 实验基础 在 C++ 中,我们可以使用 sizeof 运算符来获取对象的...

    C++对象内存布局

    ### C++对象内存布局 #### 1. 最简单的类 在C++中,理解对象的内存布局对于深入学习语言特性非常关键。通过分析一个简单的类`CTest`,我们可以更好地了解对象是如何在内存中分配和组织的。 ##### 1.1.1 赋值语句...

    C++对象内存分析

    对C++模型的认识可以从本质上提高对语言和各种机制的理解,如果对底层机制一无所知,那么很多高级的机制都只能通过死记硬背的方式来运用,而且有时候有错误,也很难找出原因。C++相对与C语言,编译器做了很多的对...

    C++对象内存池 ---- C++侦探改写.rar

    本资源"ObjPool.h"可能是一个实现了C++对象内存池的头文件,由"C++侦探改写",可能是对原内存池实现的分析和改进。下面我们将深入探讨C++对象内存池的原理、设计以及可能的优化策略。 内存池的基本思想是预先分配一...

    C++对象模型在内存中的实现

    C++对象模型在内存中的实现,讲述了类,继承以及虚继承的内存布局;成员变量和成员函数的访问已经访问时的开销情况,包含虚函数的情况,考察构造函数,析构函数,以及特殊的赋值操作符成员函数是如何工作的,数组是...

    深入探索c++对象模型 设计模式c++ pdf

    C++对象模型是C++语言的核心,它涉及到内存管理、类结构、对象生命周期、继承、多态等关键概念。在《Inside The C++ Object Model》这本书中,作者深入浅出地解析了这些概念,让读者能了解C++编译器如何将源代码转化...

    内存管理 c++ C++内存回收

    在C++中,当一个对象创建在堆上时,程序员负责在适当的时间调用`delete`来释放内存。如果忘记释放或者无法确定何时释放,就会导致内存泄漏。内存泄漏虽然可能不会立即引发问题,但随着程序运行时间的增长,累积的未...

    C++内存泄露检测器

    5. **自定义内存管理**:对于更复杂的内存管理场景,开发者可以编写自己的内存管理策略,例如使用池分配器或者追踪分配器,以便在分配和释放内存时记录更多信息,帮助定位泄漏源。 在"leakfinder.tar"这个文件中,...

    深度探索C++对象模型(简体中文版).pdf

    特别地,本书还分析了C++对象模型在运行时的语义,以及对象模型的一些边缘问题。 C++作为一门强类型语言,它的编译器对于程序员编写的代码会做出很多“手脚”,例如自动进行内存管理、调用构造函数和析构函数、处理...

    深度探索C++对象模型

    《深度探索C++对象模型》是一本专注于C++编程语言底层机制的专业书籍,它揭示了C++对象在内存中的表示方式以及对象模型的工作原理。这本书是面向已经对C++有一定基础理解的开发者,旨在帮助他们深入理解C++的内部...

    C++内存池实现

    通过阅读和分析这个项目,开发者可以深入理解内存池的实现细节,学习如何在C++中有效地管理内存,这对于优化程序性能、减少系统资源消耗是非常有价值的。同时,这也为理解和实现其他内存管理技术,如智能指针、垃圾...

    分析c++对象在内存中的布局情况.pdf

    标题中的“分析c++对象在内存中的布局情况”是指探讨C++编程中对象在内存中的存储方式,包括成员变量的排列、内存对齐原则以及如何通过特定编译器选项(如VS2010的/d1reportSingleClassLayout)来查看这种布局。...

    pascal转c++_pascal转c++教程_

    5. **面向对象特性**: - Pascal 有一些面向对象特性(如 `class`),但在 C++ 中,面向对象编程更为强大,包括类、继承、多态和封装。 6. **内存管理**: - Pascal 通常由编译器管理内存,而 C++ 需要程序员手动...

    C++对象模型.pdf

    《深度探索C++对象模型》这本书,由Stanley B. Lippman撰写,侯捷翻译,由华中科技大学出版社出版。本书致力于深入解析C++编译器在处理C++代码时所采取的复杂对象模型及其背后的底层机制,特别是针对构造函数、解构...

    几种内存池的实现(c/c++ 源码)

    在C/C++编程中,内存池常用于频繁创建和销毁小对象的场景,如网络编程、数据库连接等。本文将深入探讨几种内存池的实现方式及其源码分析。 1. **静态内存池**: 静态内存池在程序启动时就分配好内存,且在程序运行...

    C++ 内存管理算法和实现

    C++中可以使用静态分析工具如Valgrind,或者在代码中加入特定的检测机制,如引用计数,来帮助检测内存泄漏。 七、C++11及以后的内存管理改进 从C++11开始,标准库增加了对内存管理的支持,例如引入了右值引用...

    C++对象池源码示例

    总的来说,C++对象池是一种优化技术,它通过集中管理对象的生命周期,减少了内存分配和释放的开销,提升了程序运行效率。理解和掌握对象池的设计与实现,对于提升C++编程能力、优化系统性能具有重要意义。

    C++转C#的自动工具

    C++和C#虽然都是面向对象的编程语言,但它们在语法、内存管理、类型系统和库支持等方面存在显著差异。 C++是一种静态类型的、编译式的、通用的、大小写敏感的、不仅支持过程化编程,也支持面向对象编程的编程语言。...

    C++代码转java工具

    5. **内存管理**:C++使用手动内存管理,而Java有自动垃圾回收,工具需要处理这两者之间的差异。 6. **函数调用和库集成**:如果C++代码使用了库,工具可能需要处理库的迁移问题,或者提供Java的等价实现。 标签...

    C++内存检测器

    标题 "C++内存检测器" 指向的是一个用于检测C++程序中内存泄漏问题的工具或技术。在C++编程中,由于手动管理内存的特性,开发者需要自行负责内存的分配与释放。如果不小心忘记释放已分配的内存,就会导致内存泄漏,...

Global site tag (gtag.js) - Google Analytics