类定义末尾必须加分号,否则编译报错;栈对象自动管理生命周期,堆对象需手动或智能指针管理;未定义构造函数时内置成员不初始化;private成员不可外部访问,const函数不改变访问权限。

类定义必须写分号结尾,否则编译器直接报错
很多人写完 class MyClass { ... } 忘记末尾加 ;,结果编译器报出一堆看不懂的错误,比如 expected unqualified-id before 'public' 或者直接卡在下一行代码上。C++ 类定义是声明语句,和结构体一样,结尾需要分号——这不是风格问题,是语法硬性要求。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 所有类定义(无论是否带模板、继承或访问控制)末尾都补上
; - 用 IDE 时开启括号/分号自动补全,但别依赖它;手动敲完
}后立刻按; - 如果类定义嵌套在命名空间里,分号仍属于类本身,不是命名空间的结束符
对象创建:栈上 vs 堆上,内存生命周期差得远
写 MyClass obj; 和 MyClass* ptr = new MyClass(); 看似都在“创建对象”,但行为完全不同:前者在栈上分配,函数返回自动销毁;后者在堆上分配,不手动 delete 就会泄漏。新手常把两者混用,尤其在函数返回对象时误用指针。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 优先用栈对象:
MyClass obj;—— 简单、安全、无须管理 - 只有明确需要动态生命周期(比如对象存活时间超出当前作用域,或大小在运行时才确定)才用
new - 用
new就必须配对delete;更推荐用std::unique_ptr<myclass></myclass>自动管理 - 返回局部栈对象?没问题,C++17 起 guaranteed copy elision 让它高效又安全
构造函数没写,编译器只给默认版本,别指望它做初始化
如果你没定义任何构造函数,编译器会自动生成一个默认构造函数(MyClass() = default;),但它什么也不做——成员变量不会被初始化为 0,尤其是内置类型如 int、double、指针,值是未定义的。一用就崩,或者数据错得离谱。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 只要类里有需要初始化的成员(比如指针、容器、自定义资源),必须显式写构造函数
- 用成员初始化列表(
MyClass() : x_(0), ptr_(nullptr) {})比在函数体内赋值更高效、更安全 - 想禁用默认构造?加
MyClass() = delete;,别留空让编译器猜 - 注意:如果写了带参构造,编译器就不会再生成默认构造,除非你显式写出来
private 成员不能在类外访问,但 friend 和 const 成员函数容易混淆
声明为 private: 的成员,连对象点号调用都不行,比如 obj.private_member 直接编译失败。但有人误以为 const 成员函数就能绕过访问控制,其实不能;也有人滥用 friend,结果破坏封装还引发链接错误。
实操建议:
立即学习“C++免费学习笔记(深入)”;
-
private是编译期检查,跟函数是不是const没关系;const只影响 this 指针的 cv-qualifier - 真需要外部访问私有成员?优先考虑加 public 的 getter/setter,而不是塞
friend class -
friend声明要写在类内,且需提前声明友元类型,否则链接时报undefined reference - 调试时想临时看 private 成员?用调试器(gdb / lldb)直接打印,别改访问权限凑合
类不是语法糖,它是 C++ 内存布局、生命周期和访问控制的交汇点。漏掉一个分号、搞混栈堆、忽略初始化、乱用 friend —— 都可能让程序在看似无关的地方突然出问题。这些点看着小,但每个都卡在编译或运行的临界线上。











