sizeof()是否显示C ++类开销?

时间:2012-11-05 11:16:21

标签: c++

#include <iostream>
using namespace std;

class Test {
    int a;
public:
    int getA() {
        return a;
    }

Test(): a(1){}
Test(int i): a(i){}

};



int main() {
    Test t1(100);
    cout << sizeof(t1) << " " << sizeof(1) << endl; // 4 4
    return 0;
}

似乎c ++中的类根本没有开销。 t1的大小为4,类似于整数。如果我将另一个int成员添加到Test,它会将其大小增加到8.

我本来期望的东西大于4

类没有开销是真的吗?

4 个答案:

答案 0 :(得分:4)

  

似乎c ++中的类根本没有开销。

只要一个类没有虚函数,那么,是的。你期望什么样的开销?无虚拟类只是变量的集合,具有与该类型相关联的一组函数。

class Foo {
    int a;
    int bar() const { return a*a; }
};

可以简单地替换为

struct Foo {
    int a;
}

int Foo_bar(Foo const *that) {
    return (that->a) * (that->a);
}

如果您编译了每个片段,您会看到汇编代码看起来几乎是同一个。


但是,如果添加一个虚拟功能,游戏会发生巨大变化。

答案 1 :(得分:4)

如果您使用virtual方法或virtual继承,则会产生开销。

class foo {
public:
    virtual void bar() { }
    int i;
}

在32位系统上每个实例需要8个字节,vtable指针需要4个字节,int需要4个。

答案 2 :(得分:4)

在C ++中,对象的大小不能为零。这就是为什么大多数编译器将单个冗余字节插入到没有数据的类的实例中的原因。但是,如果从这样的类继承并包含数据,编译器可以优化一个字节。

#include <iostream>

class Empty
{
};

class Derived : public Empty
{
    int data_;
};

int main(int argc, char** argv)
{
    Empty empty;
    Derived derived;
    int x;
    std::cout << sizeof(empty) << std::endl;    // 1
    std::cout << sizeof(derived) << std::endl;  // 4
    std::cout << sizeof(x) << std::endl;        // 4

    return 0;
}

这是在gcc 4.6.3上完成的,它被称为“空基础优化”。有很多微妙的方法来同时拥有数据和性能开销。在大多数情况下,虚函数是最重要的函数。

答案 3 :(得分:1)

有一些开销,例如下面的示例告诉我们:

class Test {
    char a;
public:
    virtual int getA() {
        return a;
    }    

Test(): a('a'){}
Test(char i): a(i){}
};
  1. 向类中添加虚函数会将指针(vptr)大小添加到类大小。

  2. 对齐约束。测试的大小是8而不是5.注意:我将成员a从int更改为char类型。

  3. 你的班级布局如下:

    class Test  size(8):
        +---
       0    | {vfptr}
       4    | a
            | <alignment member> (size=3)
        +---
    
      Test::$vftable@:
        | &Test_meta
        |  0
       0    | &Test::getA
    
      Test::getA this adjustor: 0