C++关于类结构体大小和构造顺序,析构顺序的测试详解

目录
  • 总结
#include <iostream>
using namespace std;
/**
1. c++的类中成员若不加修饰符的话,默认是private
2. 调用构造函数时,先递归调用最顶级的父类构造函数,再依次到子类的构造函数。
3. 调用析构函数时相反,先调用最底层的子类析构函数,再依次到父类的构造函数。
4. 空类的sizeof(A)大小为1,多个空类继承后的子类大小也是1
 */
class A{
public:
    A()
    {
        cout<<"A constructor"<<endl;
    }
    ~A()
    {
        cout<<"A destructor"<<endl;
    }
};
class B:A{
public:
    B()
    {
        cout<<"B constructor"<<endl;
    }
    ~B()
    {
        cout<<"B destructor"<<endl;
    }
};
class C:B{
public:
    C()
    {
        cout<<"C constructor"<<endl;
    }
    ~C()
    {
        cout<<"C destructor"<<endl;
    }
    virtual void eat()=0;//纯虚函数会存在一个虚函数指针。64bit系统上故大小为8
};
class D:B{
    void eat()
    {
        cout<<"D eat"<<endl;
    }
};
class E:B{
    int age;//不加修饰符的话,默认是private
public:
    int num;
    E(int a,int b):age(a),num(b){
        cout<<"E constructor"<<endl;
    };
    ~E()
    {
        cout<<"E destructor"<<endl;
    }
    void eat()
    {
        cout<<"E eat"<<endl;
    }
};
class F:C{
    //继承的类中有虚函数,存在一个虚函数指针,64bit系统上占8字节
    int age;//不加修饰符的话,默认是private
public:
    int num;
    F(int a,int b):age(a),num(b){
        cout<<"F constructor"<<endl;
    };
    ~F()
    {
        cout<<"F destructor"<<endl;
    }
    void eat()
    {
        cout<<"F eat"<<endl;
    }
};

//C++关于类结构体大小和构造顺序、析构顺序的测试。
int main()
{
    cout<<"run"<<endl;
    cout<<"sizeof(A)="<<sizeof(A)<<endl;//大小为1
    cout<<"sizeof(B)="<<sizeof(B)<<endl;//大小为1
    cout<<"sizeof(C)="<<sizeof(C)<<endl;//虚函数会存在一个虚函数指针。64bit系统上故大小为8
    cout<<"sizeof(D)="<<sizeof(D)<<endl;//大小为1,非虚函数不占用类大小。
    cout<<"sizeof(E)="<<sizeof(E)<<endl;//大小为4+4
    E e(11,22);
    cout<<"e.num="<<e.num<<endl;
    E* e2=new E(33,44);
    cout<<"e2->num="<<e2->num<<endl;
    delete e2;
    cout<<"sizeof(F)="<<sizeof(F)<<endl;//大小为8+4+4

    F f(55,66);
    cout<<"f.num="<<f.num<<endl;
    f.eat();
    return 0;
}

总结

本篇文章就到这里了,希望能给你带来帮助,也希望您能够多多关注我们的更多内容!

(0)

相关推荐

  • 正确理解C++的构造函数和析构函数

    目录 一.构造函数 二.C++类的内存模型 2.1.只定义成员函数 2.2.往空类中添加静态成员变量 2.3.再加入非静态成员变量 三.this指针 四.析构函数 一.构造函数 首先,由于类只是一个模板,因此我们在定义类时无法对成员变量初始化,比如下面代码就是错误的: class circle{ public: int m_L = 20; // Error:不允许使用数据成员初始值设定项 }; 因此,初始化只能发生在类创建对象的过程中,但是由于访问权限的原因,无法在类外访问某些成员变量,因此下面

  • C++踩坑实战之构造和析构函数

    目录 前言 构造函数 通过构造函数实现的类型转换 派生类的构造函数 析构函数 继承中的析构函数 应用 总结 前言 我是练习时长一年的 C++ 个人练习生,喜欢野指针.模板报错和未定义行为(undefined behavior).之前在写设计模式的『工厂模式』时,一脚踩到了构造.继承和 new 组合起来的坑,现在也有时间来整理一下了. 构造函数 众所周知:在创建对象时,防止有些成员没有被初始化导致不必要的错误,在创建对象的时候自动调用构造函数(无声明类型),完成成员的初始化.即: Class c

  • 解析c++中参数对象与局部对象的析构顺序的详解

    下面是c++的源码: 复制代码 代码如下: class X  {public:   int i;   int j;   ~X() {} };void f(X x) {  X x1;  x.i = 1;  x.j = 2; }int main() {    f(X());} 下面是main函数的汇编码: 复制代码 代码如下: _main    PROC ; 15   : int main() { push    ebp    mov    ebp, esp    sub    esp, 8;为临时

  • C++如何计算结构体与对象的大小

    如何计算结构体的大小 其实计算一个结构的大小的方法并不难,简单来说就是把结构体内的所有成员的大小相加就可以.但是,需要内存对齐那么究竟什么是内存对齐,又为什么要进行类型对齐呢? 结构体的内存对齐 结构体内存对齐主要有两个步骤: 1.结构体各成员对齐. 2.结构体总体对齐 结构体内存对齐规则: 1.结构体的第一个成员在存放在结构体偏移量为0的位置 2.其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处.. 对齐数 = 编译器默认的一个对齐数与该成员大小的较小值. /* **VS中默认的值为8

  • 结构体对齐的规则详解及C++代码验证

    目录 基本概念 结构体对齐的规则 程序验证 基本概念 CPU一次能读取多少个字节的数据主要是看数据总线是多少位的,16位CPU一次能读取2个字节,32位CPU一次能读取4个字节,64位CPU一次能读取8个字节.并且不能跨内存区间访问,这句话的意思可以理解为,如果CPU是32位的话,那么可以将整个内存区间每4个字节分为一块(BLOCK),每次读取一个BLOCK的数据. 那么对于下面这个结构体: struct st { char c; int i; }; 如果不进行对齐操作,char 的地址范围0x

  • C++关于类结构体大小和构造顺序,析构顺序的测试详解

    目录 总结 #include <iostream> using namespace std; /** 1. c++的类中成员若不加修饰符的话,默认是private 2. 调用构造函数时,先递归调用最顶级的父类构造函数,再依次到子类的构造函数. 3. 调用析构函数时相反,先调用最底层的子类析构函数,再依次到父类的构造函数. 4. 空类的sizeof(A)大小为1,多个空类继承后的子类大小也是1 */ class A{ public: A() { cout<<"A const

  • C++类的构造与析构特点及作用详解

    目录 一.类的构造函数 什么是构造函数 构造函数的特点 构造函数的作用 二.类的析构函数 什么是析构函数 析构函数的特点 小结 析构函数的作用 总结 构造函数 析构函数 一.类的构造函数 什么是构造函数 和类具有相同名称,并且没有返回值类型的函数,就是类的构造函数 概念模糊.直接举例: #include <stdio.h> #include <windows.h> struct Test { Test() // 和类具有相同的名.并且没有返回值 { } }; int main()

  • C++继承中的对象构造与析构和赋值重载详解

    目录 一.构造/析构顺序及继承性 二.拷贝构造的继承性 三.赋值重载不具有继承性 总结 一.构造/析构顺序及继承性 class A { private: int _a; public: A(int a = 0): _a(a) { cout << "A()" << this << endl; } ~A() { cout << "~A()"<< this <<endl; } }; class B :

  • 在python中按照特定顺序访问字典的方法详解

    最近使用python写一些东西,在参考资料的时候发现字典是没有顺序的,那么怎么样按照一定顺序访问字典呐,我找到了一个小方法: 假设一个字典是: D = {'a': '1', 'b': '2', 'c': '3'} 如果我们要按照a, b, c的顺序访问字典,可以借助一个列表,比如说: L = list(D.keys()) L.sort() for key in L: print(key, 'is' D[key]) 输出为: a is 1 b is 2 c is 3 需要倒序的话只需使用倒序函数排

  • Springmvc拦截器执行顺序及各方法作用详解

    实现HandlerInterceptor接口或者继承HandlerInterceptor的子类,比如Spring 已经提供的实现了HandlerInterceptor 接口的抽象类HandlerInterceptorAdapter ,下面讲实现其接口的写法,先看一下这个接口的三个方法. - 方法preHandle: 顾名思义,该方法将在请求处理之前进行调用,在controller之前执行.SpringMVC 中的Interceptor 是链式的调用的,在一个应用中或者说是在一个请求中可以同时存在

  • 微信小程序 获取手机号 JavaScript解密示例代码详解

    当我们在开发微信小程序中,有一个常用的功能,就是获取用户的手机号,然后一键登入小程序,那么手机号如何获取呢?请认真看完本文,保证可以获取到用户的手机号. 刚开始开发微信小程序的时候,想着实现手机验证码登入,后来查阅资料得知,发给用户的短信是要自己付费的.后来想想,微信获取用户的手机号一样可以保证手机号码的真实性,因为手机号既然可以绑定微信,那么肯定是被严格核验过的,然后就开始了获取手机号之旅,网上教程有很多,但不知什么原因,都是会少一些内容,有的只有前端代码,没有后端:有的后端代码是PHP,不是

  • 微信小程序本作用域下调用全局JS详解及实例

    微信小程序本作用域下调用全局JS详解 本地wxml文件 <view> app版本:{{version}} </view> 本地js文件 var app; Page({ data:{ }, onLoad:function() { app = getApp(); this.setData({version:app.globalData.appName}); } }) 全局js文件 //app.js App({ globalData:{ appName:"hcoder"

  • 微信小程序 利用css实现遮罩效果实例详解

    微信小程序 利用css实现遮罩效果实例详解 实现效果图: 如图所示,使用css实现小程序的遮罩效果,代码如下 js文件代码: //index.js //获取应用实例 var app = getApp() Page({ data: { flag: false }, a: function(){ this.setData({flag: false}) }, b: function(){ this.setData({flag: true}) } }) wxss文件代码: .b1{position:fi

  • Thinkphp5微信小程序获取用户信息接口的实例详解

    Thinkphp5微信小程序获取用户信息接口的实例详解 首先在官网下载示例代码, 选php的, 这里有个坑 官方的php文件,编码是UTF-8+的, 所以要把文件改为UTF-8 然后在Thinkphp5 extend文件夹下建立Wxxcx命名空间,把官方的几个类文件放进去(这里要注意文件夹名, 命名空间名, 类名的, 大小写,一定要一样,官方的文件名和类名大小写不一样) 然后是自己的thinkphp接口代码: <?php /** * Created by PhpStorm. * User: le

  • 微信小程序图片自适应支持多图实例详解

    微信小程序图片自适应支持多图实例详解 微信小程序图片自适应,是一个比较常见的需求,平时我们在WEBView中,只需要设置max-width:100%.在微信里面虽然widthFix也能实现,但有一个缺陷就是图片的宽度值要大于或者等于设定的值,否则就会发生拉伸变形,本文通过另外一种来适应. 首先我们来看看图片组件给的一些说明: 属性名 类型 默认值 说明 src String 图片资源地址 mode String 'scaleToFill' 图片裁剪.缩放的模式 binderror HandleE

随机推荐