C++ -- 关于类对象的内存分析

本文探讨了C++类对象的内存分析,包括没有数据成员、只有成员函数、含有不同数据成员、带有虚函数以及继承场景下的内存大小。通过实例代码在Linux 64 bit系统上使用GCC编译,解释了编译器如何处理对象内存,如内存对齐、虚函数指针等。同时,提出了多继承和虚继承等更深入的内存问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

C++是一种可以操作内存的编程语言,虽然说类对象的内存布局会随着编译器以及运行环境的影响而受到变化。但是通过一些简单的分析还是可以加深自己对语言本身的理解。

我们来看几种情况:读者可以不看下面的具体分析,只是询问一下自己,它们的大小,你知道吗?

  • 没有任何数据成员的类
  • 只有成员函数但没有数据成员的类
  • 拥有一个整形数的类
  • 拥有一个整形和字符整形(char)的类
  • 带有虚函数的类
  • 继承拥有虚函数父类的子类

先贴代码:

#include <iostream>
#include <string>

class Foo
{
};

class FooWithFunction
{
};

class FooWithInt
{
    int i;
};

class FooWithIntChar
{
    int i;
    char c;
};

class Test
{
  public:
    virtual void foo() {}
};

class Derived : public Test
{
  public:
    virtual void derivedFoo() {}
};



int main()
{
    std::cout << "Foo size: \t\t\t" << sizeof(Foo) << std::endl;
    std::cout << "FooWithFunction size: \t\t" << sizeof(FooWithFunction) << std::endl;
    std::cout << "FooWithInt size: \t\t" << sizeof(FooWithInt) << std::endl;
    std::cout << "FooWithIntChar size: \t\t" << sizeof(FooWithIntChar) << std::endl;
    std::cout << "Test with virtual function: \t" << sizeof(Test) << std::endl;
    std::cout << "Pointer size: \t\t\t" << sizeof(int *) << std::endl;

    Derived d;
    std::cout << "Derived object size: \t\t" << sizeof(d) << std::endl;
    return 0;
}
Foo size: 			1
FooWithFunction size: 		1
FooWithInt size: 		4
FooWithIntChar size: 		8
Test with virtual function: 	8
Pointer size: 			8
Derived object size: 		8

注,以上代码在Linux 64 bit系统上使用GCC编译通过

为什么是这样的呢?

  1. 对于没有任何类成员的类,编译器通常只是为了标记它,分配最小的空间。至于为什么不是0,也不是另一个更大的数,我觉得是为了性能和实现的妥协。
  2. 只有成员函数,而没有数据成员,这不会增加对象的内存大小。成员函数所占据的空间都在代码段上。和数据不在一起。
  3. 这里的整形数是4个字节,可能在不同的平台上会不一样。
  4. 在默认的情况下,编译器会做一些内存的对齐,所以Char被撑大到四个字节。
  5. 对象内部会包含一个虚函数指针,在64位系统中,一个指针是需要8个字节来表示的。
  6. 继承如果不增加数据成员的情况下,并不会增加对象的大小,同样包含一个虚函数指针。

这里其实只是C++对象内存模型的一个很简要描述,还有一些延伸的问题。

  • 多继承情况下,对象的内存又会变成什么样呢?
  • 虚继承场景

...

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值