类是编译器识别的内存布局规则与函数绑定约定,本质为结构体加vtable语法糖;空类sizeof为1,含虚函数则至少8字节;对象内存位置决定生命周期,this是隐式传入的常量指针。
类和对象不是“抽象”和“具体”的哲学对应,而是编译器能识别的内存布局规则 + 函数绑定约定。
C++ 类在内存中没有独立存在形式——它只是编译器用来组织数据和函数的一套规则。普通成员函数不占用对象内存,只有非静态数据成员才真实占据空间;虚函数会触发编译器生成 vtable,并在每个对象开头隐式插入一个 vptr 指针(大小通常为 8 字节,在 64 位系统上)。
class A {}; 的 sizeof(A) 是 1,不是 0——这是为了保证不同对象有唯一地址virtual void f();,sizeof 至少为 8(x64)vtable 越大,但对象实例只存一个 vptr
是否用 new 不代表“是不是对象”,只决定内存分配位置和析构时机。
A a; → 栈上对象,作用域结束自动调用 ~A()
A* p = new A; → 堆上对象,需手动 delete p;,否则泄漏static A s; → 全局/静态区对象,程序启动时构造,结束时析构this 指针,但不是“属于对象”的证据this 是编译器自动传入的常量指针(类型为 A* const),它让成员函数能访问当前对象的数据,但它本身不存储在对象内部。
this,也不能取它的地址(&this 是非法的)void func() { cout 打印的是对象首地址,不是“函数归属证明”this,所以不能访问非静态成员——这不是限制,是逻辑必然真正容易被忽略的点:类定义阶段不分配内存,对象定义才触发构造;而继承关系中的内存布局(比如虚基类偏移)、std::move 后对象状态、以及 constexpr 构造函数对编译期求值的影响,才是实际编码中踩坑最多的地方。