zoukankan      html  css  js  c++  java
  • 空类的大小

    空类就是没有任何数据成员的类,这种类占用的内存大小在不同的语言里面有不同的实现

    c

    struct A {};
    
    printf("sizeof(A): %lu
    ", sizeof(struct A));
    // sizeof(A): 0
    

    这个结果输出是0,也就是说 c 语言中的空类大小为 0

    struct A a1;
    struct A a2;
    printf("address(a1): %p
    ", &a1);
    printf("address(a2): %p
    ", &a2);
    printf("&a1 == &a2: %d
    ", &a1 == &a2);
    // address(a1): 0x7ffdead15ff0
    // address(a2): 0x7ffdead15ff0
    // &a1 == &a2: 0
    

    在 gcc 中,两个空类拥有相同的地址,但是比较的结果却是不同的……这个我也不知道咋解释……

    c++

    class A {};
    
    std::cout << "sizeof(A): " << sizeof(A) << std::endl;
    // sizeof(A): 1
    

    c++ 的空类大小为1,因为 c++ 中规定不同的对象必须拥有不同的地址,如果为0会导致两个空类的地址一样

    class B {
        A a1;
        A a2;
    };
    
    std::cout << "sizeof(B): " << sizeof(B) << std::endl;
    // sizeof(B): 2
    

    空类作为成员,按照大小为 1 来处理

    class C : public A {};
    
    std::cout << "sizeof(C): " << sizeof(C) << std::endl;
    // sizeof(C): 1
    
    class D : public A {
        int i;
    };
    
    std::cout << "sizeof(D): " << sizeof(D) << std::endl;
    // sizeof(D): 4
    

    基类为空类不占空间,这个就是空白基类优化 EBO (empty base optimization)

    golang

    type A struct{}
    
    fmt.Println("sizeof(A):", unsafe.Sizeof(A{}))
    // sizeof(A): 0
    

    golang 中空类的大小为 0

    a1 := A{}
    a2 := A{}
    fmt.Printf("a1 == a2: %v
    ", &a1 == &a2)
    // a1 == a2: false
    

    两个空类对象在栈上拥有不同的地址

    a3 := A{}
    a4 := A{}
    fmt.Printf("address(a3): %p
    ", &a3) // a3 逃逸到堆区
    fmt.Printf("address(a4): %p
    ", &a4) // a4 逃逸到堆区
    fmt.Printf("a3 == a4: %v
    ", &a3 == &a4)
    // address(a3): 0x1190fd0
    // address(a4): 0x1190fd0
    // a3 == a4: true
    

    调用 printf,a3、a4 逃逸到了堆区,在堆区拥有相同的地址

    这个地方确实很怪,仅仅因为调用了一次 printf,导致 &a1 == &a2 的判断出现了不同的结果

    总结

    个人感觉 c++ 的设计不是很好,首先空类也占用一个字节的空间就是一件让人困惑的事情,所以不得不花很多篇幅去解释这个问题,还要去解决由这个问题引发的空类组合和继承的问题;另外对于空类是不是一定要有不同的地址来去区分不同的对象,这个场景在实际的生产中基本没有碰到过,就算是真的有这样的场景,也可以让用户自己增加成员变量去实现;最重要的,这样的设计会带来不必要的内存和性能的开销,而这种开销还不可避免

    链接

    转载请注明出处
    本文链接:https://tech.hatlonely.com/article/58

  • 相关阅读:
    用IntelliJ IDEA 开发Spring+SpringMVC+Mybatis框架 分步搭建一:建立MAVEN Web项目
    jvm学习笔记二(减少GC开销的建议)
    jvm学习笔记一(垃圾回收算法)
    【转】 StringUtils中 isNotEmpty 和isNotBlank的区别
    单例模式
    工厂模式
    个人项目作业
    第一次作业-热身!
    第四单元总结
    第三单元总结
  • 原文地址:https://www.cnblogs.com/hatlonely/p/11945382.html
Copyright © 2011-2022 走看看