C++类中成员变量占用对象内存、决定对象大小,成员函数不占对象内存、仅一份代码通过this指针访问数据;二者在内存布局、访问机制和语义上本质不同。

在C++中,类的内部结构由成员变量(数据)和成员函数(行为)共同构成,二者在内存布局、访问方式和语义上截然不同——成员变量占用对象实例的内存空间,而成员函数不随对象重复存储,只有一份代码体,通过隐式 this 指针访问对应对象的数据。
成员变量:对象的“身体”,决定对象大小
成员变量是类的数据组成部分,每个对象实例都拥有自己独立的一份副本(静态成员除外)。它们按声明顺序(考虑对齐)依次排布在对象的内存中,直接影响 sizeof(类名) 的结果。
- 普通成员变量(如 int x;、std::string name;)属于每个对象私有,修改一个对象的值不影响其他对象
- static 成员变量属于整个类,所有对象共享同一份,不计入单个对象的内存大小,必须在类外定义(如 int MyClass::count = 0;)
- const 成员变量必须用构造函数初始化列表初始化;mutable 成员可在 const 成员函数中被修改
成员函数:对象的“动作”,不占对象内存
成员函数的代码只在编译后生成一份,存于代码段。调用时,编译器自动传入隐式 this 指针(指向当前对象),从而让函数能访问该对象的成员变量。
- 非静态成员函数本质是带有一个额外 this 参数的普通函数,例如 void setX(int v) 等价于 void setX(MyClass* this, int v)
- static 成员函数没有 this 指针,只能访问 static 成员变量和其他 static 成员函数
- const 成员函数(如 int getX() const)表示承诺不修改对象状态,此时 this 类型为 const MyClass*
内存布局与访问的本质区别
假设定义 class Person { public: int id; std::string name; void print() const; };:
立即学习“C++免费学习笔记(深入)”;
- 每个 Person p1, p2; 占用独立内存,含各自的 id 和 name 数据
- p1.print() 和 p2.print() 调用的是同一段机器码,但运行时 this 分别指向 p1 和 p2 的起始地址
- 取地址操作 &p1.id 得到有效数据地址;而 &Person::print 得到的是函数指针,不是对象内偏移
常见误区提醒
初学者容易混淆的几个点:
- “函数存在对象里”是错觉——对象里只有数据,函数代码在别处;sizeof 不包含成员函数体积
- 不能在类内直接给非 static 成员变量赋值(如 int x = 42; 是 C++11 起允许的 默认成员初始化,本质仍由构造函数实现,并非定义时分配)
- 空类 class A {}; 的 sizeof 为 1(非零保证不同对象地址唯一),不含任何函数或变量
基本上就这些。理解成员变量与成员函数在语义、生命周期和内存中的根本差异,是掌握 C++ 类模型的关键一步。









