深度探索c++对象模型读书笔记:Data语意学-继承与Data member中内存对齐问题

书中在继承之后内存对齐问题上说道下面代码:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 class A
 4 {
 5 private:
 6     int val;
 7     char bit1;
 8 };
 9 class B : public A
10 {
11 private:
12     char bit2;
13 };
14 class C : public B
15 {
16 private:
17     char bit3;
18 };
19 int main()
20 {
21     cout << sizeof(A) << endl << sizeof(B) << endl << sizeof(C) << endl;
22     return 0;
23 }

并说输出应该为8 12 16,并说明了这样做的理由,当时我就觉得那个理由很奇怪,或者说没看懂书中所说的理由到底是什么,于是进行了测试,发现gcc编译器中输出的结果为8 8 8,说明确实bit2,bit3和bit1绑定在了一起,起码书中的说法在现在的gcc编译器上是错误的。

时间: 2024-08-04 22:16:53

深度探索c++对象模型读书笔记:Data语意学-继承与Data member中内存对齐问题的相关文章

【C++】深度探索C++对象模型读书笔记--执行期语意学(Runtime Semantics)

对象的构造和析构: 全局对象 C++程序中所有的global objects都被放置在程序的data segment中.如果显式指定给它一个值,此object将以此值为初值.否则object所配置到的内容为0. 如果全局对象如果有构造函数或析构函数的话,我们说它需要静态的初始化操作和内存释放操作.编译器的执行步骤如下: 1.为每一个需要静态初始化的文件产生一个_sti()函数,内含必要的构造函数调用操作. 2. 在每一个需要静态的内存释放操作的文件中,产生一个_std()函数,内含必要的析构操作

【C++】深度探索C++对象模型读书笔记--Data语意学(The Semantics of data)

1. 一个空类的大小是1 byte.这是为了让这一类的两个对象得以在内存中配置独一无二的地址. 2. Nonstatic data member 放置的是“个别的class object”感兴趣的数据,static data members则放置的是“整个class”感兴趣的数据. 3. C++对象模型把nonstatic data members直接放在每一个classs object之中.对于继承而来的nonstatic data members(不管是virtual 还是nonvirtua

【C++】深度探索C++对象模型读书笔记--关于对象(Object Lessons)

前言中的内容: 1.什么是C++对象模型? 1.语言中直接支持面向对象程序设计的部分 2. 对于各种支持的底层实现机制 2. C++ class的完整virtual functions在编译时期就固定下来了,程序员没有办法再执行器动态增加或取代其中一个.这使得虚拟调用操作得以快速地派送结果,付出的成本则是执行期的弹性. 3. 全局对象在main()函数之前便完成初始化. 第一章 关于对象 1. 在C++中,有两种class data members:static 和 nonstatic,以及三种

【C++】深度探索C++对象模型读书笔记--Function(The Semantics of Function)

1. Nonstatic member function(非静态成员函数)的调用方式 编译器会将”member 函数实例“转换为对等的”nonmember函数实例“. 对于非静态成员函数 float Point3d::magnitude3d() const{...} 转换步骤如下: 1. 改写函数的signature(意指:函数原型)以安插一个额外的参数到member function中,用以提供一个存取管道,使class object得以将此函数调用.该额外参数被称为this指针: //non

【C++】深度探索C++对象模型读书笔记--构造函数语义学(The Semantics of constructors)(四)

成员们的初始化队伍(member Initia 有四种情况必须使用member initialization list: 1. 当初始化一个reference member时: 2. 当初始化一个const member时: 3. 当调用一个base class的constructor,而它拥有一组参数时: 4.当调用一个member class的constructor,而它拥有一组参数时: 在这四种情况下,程序可以被正确编译运行,但是效率不高.例如: 1 class Word { 2 Stri

深度探索C++对象模型 第二章构造函数语意学

在使用C++时,常常会好奇或者抱怨,编译器为我们做了什么事呢? 为什么构造函数没有为我初始化呢?为什么我还要写默认构造函数呢? 2.1 Default Constructor 的构造操作 如果没有声明默认构造函数,编译器会在需要的时候帮我们产生出来. 为了避免在多个地方被需要导致重复,则编译器将产生的构造函数声明为inline方式. class Foo {public:Foo(), Foo(int) }; class Bar {public: Foo foo;char *str;} Bar ba

深入探索C++对象模型 读书笔记

第1章 关于对象 1.C++在布局以及存取时间上的主要的额外负担是由virtual引起的,包括: a.virtual function机制,引入vptr以及vtbl,支持一个有效率的"执行期绑定" b.virtual base class,用以实现"多次出现在继承体系中的base class,有一个单一而被共享的实例" c.多重继承下,派生类跟第二个以及后续基类之间的转换 2."指针的类型"会教导编译器如何解释某个特定地址中的内存内容以及其大小(

Android深度探索——第八章读书笔记及心得

蜂鸣器驱动 ——第8章读书笔记及心得 通过本章的学习,学会了pwm的驱动实验,知道了蜂鸣器实现的原理.蜂鸣器是开发板上的一个硬件设备,可以通过向寄存器写入特定的值来控制蜂鸣器发出尖叫声.本实验将linux驱动区分成了多个实现文件.学会了编写Makefile文件.知道了linux驱动模块的依赖.通过实验学会了linux驱动常用的代码重用方式及强行卸载linux驱动的方法. 在C语言中编译多个源代码文件时,如果a.c使用了b.c文件中的函数,需要在a.c文件中使用extern预先定义b.c中的函数,

Android深度探索——第九章读书笔记及心得

HAL模块 ——第9章读书笔记及心得 通过本章学习学会了Android中特有的与linux驱动交互的方法,即通过HAL模块.HAL模块本质上就是通过linux共享库(.so)与linux交互驱动,然后利用应用程序再访问linux共享库.每一个HAL共享库指定一个ID,在利用这个ID配合一定的规则找到linux共享库.知道了HAL对于Android的意义.知道了Android HAL的架构. HAL是建立在linux驱动之上的一套不属于linux内核的程序库.它属于linux内核层之上的应用层.H