首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

sizeof 知多少?

由于联合体需要共用内存,所以其大小是其成员的最大大小,再加上根据联合体对齐值进行填充的数据大小(需要填充的原因和结构体一致),而联合体的对齐值则跟结构体一样,为其成员的最大对齐值 使用公式依然会更清晰一些...public cv1 { short m_2; virtual ~cv2() {}; }; 一般而言,如果基类或者继承类存在虚函数表指针的话,vptr会置于类型的内存布局首部(继承类会复用基类的虚函数表指针...多继承 C++还支持多继承特性,一个类型可以继承于多个基类(假设基类分别为B1, B2, …, Bn),其中每个基类都可能有成员数据及虚函数表,继承类I也必须能够无缝的向下转形为任一基类,其内存布局的一般规则如下...,相反,GCC”合并”了虚函数表指针(vptr)和虚基类表指针(vbptr), 或者说GCC只使用了vptr来实现虚函数的重载和虚基类的索引,方法是通过正向索引vptr来定位虚函数(vptr + offset...(即空基类优化),所以实际上s8的大小一般为4,当然,如果你把此时的空类型看做一种大小为0,对齐值为1的结构的话,仍然可以使用之前的公式计算得出正确答案: 首先对齐各个成员: sizeof’(s8, 0

52300

C++11 POD类型

在某些情况下,布局是有规范明确的定义,但如果类或结构包含某些 C++ 语言功能,如虚拟基类、 虚函数、 具有不同的访问控制的成员,则不同编译器会有不同的布局实现,具体取决于编译器对代码的优化方式,比如实现内存对齐...2.标准布局类型 当类或结构体满足如下几个条件时则是标准布局类型: (1)没有虚函数或虚拟基类; (2)所有非静态数据成员都具有相同的访问说明符; (3)在继承体系中最多只有一个类中有非静态数据成员...但是如果派生类的第一个非静态成员的类型和基类相同,由于C++标准要求相同类型的对象的地址必须不相同,编译器就会为基类分派一个字节的地址空间。...类型的对象内存布局应该是相同,但实际上是不同的,因为D1中基类B1和对象b都占用了1个字节,D2中基类B1为空,并不占用内存空间。...事实上,如果对象是普通类型,不是标准布局,例如类有public与private的非静态数据成员,可以使用memcpy进行二进制赋值。

1.3K21
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    C++面试知识总结

    1.程序运行知识 1.1 内存布局和分配方式 C程序的内存布局如下: 静态存储区:存储全局变量和static变量,通常在程序编译期间已经分配好了。...C++程序的内存布局与C程序布局类似,区别是C++不再区分全局变量和静态变量是否已经初始化,全部存储在静态存储区;另外堆中存放new/delete申请释放的资源,而malloc和free申请的资源存放在自由存储区...覆盖和隐藏的区别: 派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual关键字,基类的函数将被隐藏。 派生类的函数与基类的函数同名,参数也相同。...3.5 基类和子类的构造、析构顺序 定义一个对象时先调用基类的构造函数、然后调用派生类的构造函数 先派生类的析构后基类的析构,也就是说在基类的的析构调用的时候,派生类的信息已经全部销毁了 3.6 深拷贝与浅拷贝的区别...,派生类的成员函数可以访问基类中的公有和受保护成员;公有继承时基类受保护的成员,可以通过派生类对象访问但不能修改。

    1.8K41

    【愚公系列】2023年11月 WPF控件专题 2023秋招WPF高频面试题

    Dispatcher: 一个抽象基类,用于绑定到一个线程上的类。与Windows窗体类似,WPF也要求仅从创建线程中调用方法和属性。...通过继承自DispathcerObject类,用户界面中的每个元素都可以检查代码是否在正确的线程上运行,并能通过访问调度程序为用户界面线程封送代码。Dependency: 所有支持依赖属性的类的基类。...这个类包含点击测试和转换等特性UI Element: 所有需要基本显示功能的WPF元素的抽象基类是UIElement。...这个类提供了鼠标移动,拖放,按键的通道和起泡事件;提供了可以由派生类重写的虚显示方法;以及布局方法。...ContentControl 是包含其他元素并具有 Content 属性(例如,Button)的控件的基类。 ContentPresenter 用于在控件模板中显示内容。

    53222

    sizeof 知多少? (下)

    ),然后放置基类的数据成员,最后放置继承类的数据成员,放置方法仍然遵循之前所讲的对齐和填充规则,所以我们仍然可以套用公式来计算cv2的大小: 首先对齐各个成员: sizeof’(cv2, 0) = 0...多继承 C++还支持多继承特性,一个类型可以继承于多个基类(假设基类分别为B1, B2, …, Bn),其中每个基类都可能有成员数据及虚函数表,继承类I也必须能够无缝的向下转形为任一基类,其内存布局的一般规则如下...接着放置B2的数据成员,并逐个执行内存对齐 e. 对接下来的基类Bi重复c和d两个步骤,直到 Bn f. 接着放置I自身的数据成员,并逐个执行内存对齐 g....,相反,GCC”合并”了虚函数表指针(vptr)和虚基类表指针(vbptr), 或者说GCC只使用了vptr来实现虚函数的重载和虚基类的索引,方法是通过正向索引vptr来定位虚函数(vptr + offset...(即空基类优化),所以实际上s8的大小一般为4,当然,如果你把此时的空类型看做一种大小为0,对齐值为1的结构的话,仍然可以使用之前的公式计算得出正确答案: 首先对齐各个成员: sizeof’(s8, 0

    64700

    C++中的POD类型

    POD类型的优势 1. C内存布局兼容 POD类型兼容C内存布局,C++可以直接使用C库函数操作POD数据类型,POD类型在C和C++间的操作总是安全的。 2....POD类型的具体要求如下(这里只讨论类类型,即class、struct和union): 1. trival 一个类类型是trival的需要满足如下条件: 默认指的是编译器自动生成的版本,用户定义的拷贝控制操作即使函数体为空也不算...默认的构造函数与析构函数 默认的拷贝构造函数和移动构造函数 默认的拷贝赋值运算符和移动赋值运算符 不能包含虚函数和虚基类 2....标准布局 所有非静态数据均为标准布局类型 所有基类均为标准布局类型 所有非静态成员具有相同的访问权限 没有虚函数 没有虚基类 类中的第一个非静态成员与其任何基类的类型不同 要么所有基类都没有非静态成员,...要么最下层的子类没有非静态成员且最多只有基类有非静态数据成员(总之继承树中最多只能有一个类有非静态数据成员) Reference [1] https://zhuanlan.zhihu.com/p/45545035

    3K41

    我们通常说的POD到底是什么?

    Standard layout 布局指的是类、结构体或者联合(Union)的成员在内存中的排列。标准布局定义了这样一种类型,它不使用C中不存在的而在CPP中存在的某些功能或者特性。...如果某个类是标准布局,那么可以通过memcpy进行复制,而且可以与C语言中定义的同种类型进行交互。一言以蔽之,具有标准布局类的类或者结构体等与C兼容,并行可以通过C的API进行交互。...既然符合标准布局的类只具有C语言中存在的功能或者特性,那么,很容易总结出来标准布局的条件: 1. 没有虚函数或者虚基类 2. 没有引用类型的非静态成员变量 3....所有的非静态成员变量具有相同的访问控制权限 4. 所有的非静态成员变量和基类都是标准布局 5. 没有多重继承导致的菱形问题 6. 子类中的第一个非静态成员的类型与其基类不同 7....,上述几个类A、B、C和D都是标准布局。

    83142

    图说C++对象模型:对象内存布局详解

    在表格驱动对象模型中,我们可以为子类对象增加第三个指针:基类指针(bptr),基类指针指向指向一个基类表(base class table),同样的,由于间接性导致了空间和存取时间上的额外负担,优点则是无须改变子类对象本身就可以更改基类...,如果它有虚基类指针,那么虚基类指针可能在实例的0字节偏移处(该类没有vptr时,vbptr就处于类实例内存布局的最前面,否则vptr处于类实例内存布局的最前面),也可能在类实例的4字节偏移处。...总结一下: 不考虑虚函数与虚继承,当数据都在同一个访问标识符下,C++的类与C语言的结构体在对象大小和内存布局上是一致的,C++的封装并没有带来空间时间上的影响。...7.2.下面这个空类构成的继承层次中,每个类的大小是多少?...b1虚继承于b,编译器为其安插一个4字节的虚基类表指针(32为机器),此时b1已不为空,编译器不再为其安插1字节的char(优化)。 b2同理。 d含有来自b1与b2两个父类的两个虚基类表指针。

    4.2K43

    如何将GridViewEX升级到UWP(Universal Windows Platform)平台

    引言 上一篇文章中,我们主要讲解了如何在保证GridView控件的用户体验基础上,扩展GridView生成GridViewEx控件,增加动态添加新分组功能等,本文在上文的基础上,介绍如何在Windows10...修改布局和导航 VisibilityConverter 和 SuspensionsManager暂时不需要修改,可直接在UWP中使用。主要修改布局和导航逻辑文件。...因此只需要开发一个基类,应用到不同的Xaml 页面中就可以实现轻松实现导航功能,不需要重复编写代码。...如果想保证应用程序在Windows10中具有与系统一致的界面风格和用户体验,可使用Windows 10 ThemeResources (主题资源)。 2...., 1); 19: } 20: } 在多设备中具有良好用户体验 为了适应多种设备,需要生成自适应布局。

    2.8K80

    C语言与C++面试知识总结

    联合有如下特点: 默认访问控制符为 public 可以含有构造函数、析构函数 不能含有引用类型的成员 不能继承自其他类,不能作为基类 不能含有虚函数 匿名 union 在定义所在作用域可直接访问 union...底层实现原理与编译器相关,一般通过虚基类指针和虚基类表实现,每个虚继承的子类都有一个虚基类指针(占用一个指针的存储空间,4字节)和虚基类表(不占用类对象的存储空间)(需要强调的是,虚基类依旧会在子类里面存在拷贝...实际上,vbptr 指的是虚基类表指针(virtual base table pointer),该指针指向了一个虚基类表(virtual table),虚表中记录了虚基类与本类的偏移地址;通过偏移地址,...虚继承、虚函数 相同之处:都利用了虚指针(均占用类的存储空间)和虚表(均不占用类的存储空间) 不同之处: 虚继承 虚基类依旧存在继承类中,只占用存储空间 虚基类表存储的是虚基类相对直接继承类的偏移 虚函数...抽象类:含有纯虚函数的类 接口类:仅含有纯虚函数的抽象类 聚合类:用户可以直接访问其成员,并且具有特殊的初始化语法形式。

    5K41

    什么?CC++面试过不了?因为你还没看过这个!

    联合有如下特点: 默认访问控制符为 public 可以含有构造函数、析构函数 不能含有引用类型的成员 不能继承自其他类,不能作为基类 不能含有虚函数 匿名 union 在定义所在作用域可直接访问 union...底层实现原理与编译器相关,一般通过虚基类指针和虚基类表实现,每个虚继承的子类都有一个虚基类指针(占用一个指针的存储空间,4字节)和虚基类表(不占用类对象的存储空间)(需要强调的是,虚基类依旧会在子类里面存在拷贝...实际上,vbptr 指的是虚基类表指针(virtual base table pointer),该指针指向了一个虚基类表(virtual table),虚表中记录了虚基类与本类的偏移地址;通过偏移地址,...虚继承、虚函数 相同之处:都利用了虚指针(均占用类的存储空间)和虚表(均不占用类的存储空间) 不同之处: 虚继承 虚基类依旧存在继承类中,只占用存储空间 虚基类表存储的是虚基类相对直接继承类的偏移 虚函数...抽象类:含有纯虚函数的类 接口类:仅含有纯虚函数的抽象类 聚合类:用户可以直接访问其成员,并且具有特殊的初始化语法形式。

    3.7K50

    c++类和继承面试点25连问

    ,另外封装还有一层意义是它把某种事物具现出属性和方法并形成了一个整体,就像一个人,同时具有身高和身体等等这些,才是完整的人,如果不封装,那这个人就相当于四分五裂了; 继承,所谓继承,其实就是真实意义上讲的继承了某些东西...多重继承时类对象内存布局 非虚继承时,按照继承顺序存储,虚继承时,虚基类的内容放在一块内存的最后面存储。 详细的看之前这篇文章:c++头脑风暴-多态、虚继承、多重继承内存布局 21....类的大小由哪些因素决定?空类是多大?...空类大小为1个字节。 22. new一个类的时候发生了什么 new其实就是申请动态内存,而一个类只有虚指针和成员变量才需要内存,所以new一个类就是给虚指针和成员变量申请内存空间。 23....,结合我们知道的,如果使用了空指针,就会发生段错误,那这里肯定也会发生段错误,但实际上编译执行后并没有产生错误,print函数被正确执行了,这就很尴尬了,这是为什么呢?

    99410

    聚合体及其初始化———指派初始化器,C++长大了,你应该知道指派初始化器

    ,但是在MSVC2022 C++20的编译环境下,具有自定义析构函数的仍被认为是聚合体 聚合体元素 聚合体中的元素为: 数组:数组中所有的元素 类类型(类、结构体、联合体):所有不是匿名位域非静态数据成员...类类型(类、结构体、联合体):所有直接基类的和自己的,所有不是匿名位域和匿名联合体非静态数据成员 聚合体初始化 上文提到,可以直接使用初始化列表对聚合体进行初始化,C++20新增指派初始化器对聚合体进行初始化...,并且显示初始化元素必须是成员或成员的元素,不可指向基类的成员 如果该元素是匿名联合体成员,使用指派初始化器列表初始化时可以直接使用联合体成员的指派初始化器进行初始化。...,则(1)联合体内可变成员具有默认值,则该成员以默认值初始化。...(example 224) 如果聚合体具有一个匿名联合体成员,那么对应的指派初始化器必须指明联合体内的一个成员。

    16510

    C++多态

    类 D 同时继承 B 和 C,B 和 C 又继承自 A)体系下,虚表在各个类中的布局如何,如果类 B 和类 C 同时有一个成员变了 m,m 如何在 D 对象的内存地址上分布的,是否会相互覆盖 存在虚函数的类对象...如果对象类型是派生类,就调用派生类的函数;如果对象类型是基类,就调用基类的函数。运行期多态就是通过虚函数和虚函数表实现的。...菱形继承(类 D 同时继承 B 和 C,B 和 C 又继承自 A)体系下,虚表在各个类中的布局如何,如果类 B 和类 C 同时有一个成员变了 m,m 如何在 D 对象的内存地址上分布的,是否会相互覆盖...size计算 空类的大小为1,因为在C++中任何对象都需要有一个地址,最小为1。...当存在多重继承时,多重继承了几个基类,子类将含有几个虚指针,并且此指针具有传递性。

    1.9K10

    TS 进阶 - 类型基础

    在 TypeScript 中,symbol 类型并不具有这一特性,多个具有 symbol 类型的对象,它们的 symbol 类型指的都是 TypeScript 中的同一个类型。...# 继承、实现、抽象类 // 基类 class Base {} // 派生类 class Derived extends Base {} 基类中哪些成员可以被派生类访问,由其访问性修饰符决定。...派生类可以访问使用 public 或 protected 修饰符的基类成员。除了访问外,派生类可以覆盖基类中的方法,但仍然可以通过 super 来调用基类的方法。...O 开放封闭原则,一个类应该对扩展开放,对修改封闭 L 里氏替换原则,派生类可以在程序的任何移除对其基类进行替换,即子类完全继承父类的一切,只是对其功能进行扩展 I 接口隔离原则,类的实现方法应该只需要实现自己需要的那部分接口...非空断言是类型断言的简化,标记前面的一个声明一定是非空的,即剔除 null 和 undefined 类型: declare const foo: { func?

    1.8K50

    【编程基础】如何赢得C++面试

    4.子类析构时要调用父类的析构函数吗? 析构函数调用的次序是先派生类的析构后基类的析构,也就是说在基类的的析构调用的时候,派生类的信息已经全部销毁了。...定义一个对象时先调用基类的构造函数、然后调用派生类的构造函数;析构的时候恰好相反:先调用派生类的析构函数、然后调用基类的析构函数 5.C++中的class和struct的区别 从语法上,在C++中(只讨论...数组要么在静态存储区被创建(如全局数组),要么在栈上被创建。指针可以随时指向任意类型的内存块。 11.类成员函数的重载、覆盖和隐藏区别?...“隐藏”是指派生类的函数屏蔽了与其同名的基类函数,规则如下: (1)如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual关键字,基类的函数将被隐藏(注意别与重载混淆)。...(2)如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual关键字。

    1.4K70

    用于少样本学习的联合双路度量

    其次,在基线的基础上,我们提出了一种联合的分类双路径度量,利用基类和新类之间的相关性来进一步提高分类的准确性。...作者的动机是,对于具有新类相同标签的样本,它们在基类上的相似性分布更有可能相似,而不同类的样本应该有不同的分布。...首先计算支持集和查询集在基类上的相似性分布 ρ 和 ρ ,然后计算 ρ 和 ρ 间的相似性,即支持集和查询集之间的传递相似性 φ 。...它假设每个样本都可以用其 个最近邻线性组合来表示,降维前后线性关系的权重系数保持不变。可以看出,LLE在降维过程中具有一定的选择性,这满足了我们的期望,即样本应该集中在一些特定的基类上。...此外,使用局部线性嵌入的联合双路径度量通过降低LLE的维数来增加基类和新样本之间的非线性,因此不同的基类可以通过找到它们的 个最近邻的过程对不同的查询样本的分类产生不同的影响。 ? ?

    81420

    使用Unity3D的设计思想实现一个简单的C#赛车游戏场景

    组件(Component)是用来绑定到游戏对象(Game Object)上的一组相关属性。本质上每个组件是一个类的实例。...可以从类图中看出,GameObject作为基本对象,没有实现具体的表现和行为,而是提供了可供添加组件的方法来实现让我们可以将组件拖拽到其上边,让组件来控制GameObject的行为和展现。...其次,由于各个组件都具有一些公有的特性,因此设计了一个组件基类BaseComponent,它实现了一个Start()方法,并确保该方法只被调用一次。...最后,继承于BaseComponent设计实现各个不同的游戏组件,他们重写了一个或多个基类中实现IComponent中的方法。有了这些组件,我们就可以将其注册到游戏对象上,游戏也就因此有了活力。...  (1)设计BaseComponent类,它是各个游戏组件的基类,实现了IComponent接口,并定义了Start方法(该方法只会在开始时被执行一次)。

    1.7K30
    领券