3
#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,类似于整数。如果我向 Test 添加另一个 int 成员,它的大小将增加到 8。

我本来期望大于 4 的东西

课程没有开销是真的吗?

4

4 回答 4

5

似乎 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);
}

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


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

于 2012-11-05T11:21:04.267 回答
4

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

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

在 32 位系统上,每个实例占用 8 个字节,4 个用于 vtable 指针,4 个用于int.

于 2012-11-05T11:22:32.773 回答
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 上完成的,它被称为“空基优化”。拥有数据和性能开销的方式要少得多。在大多数情况下,虚函数是最重要的。

于 2012-11-05T11:28:06.787 回答
1

有一些开销,例如下面的示例说明了一些事情:

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

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

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

你的班级布局是这样的:

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
于 2012-11-05T11:33:23.637 回答