C++类声明必须前置,否则编译报错;构造函数名须与类名一致且无返回类型;访问控制符后需加冒号;推荐用花括号初始化避免最令人烦恼的解析;成员变量须在初始化列表中显式初始化。

类声明必须写在使用前,否则编译器不认识
C++ 不像 Python 那样允许后定义、前调用。如果你在 main() 里直接写 MyClass obj;,而 MyClass 的声明还没出现,编译器会报错:‘MyClass’ was not declared in this scope。
常见做法是把类定义放在头文件(如 myclass.h)里,或至少放在 main() 上方;如果拆成 .h + .cpp,记得在 .cpp 里 #include "myclass.h"。
- 类内只声明成员函数,不实现(除非是 inline 短函数)
- 构造函数名必须和类名完全一致,且无返回类型(连
void都不能写) - 访问控制符(
public:/private:)后面要加冒号,漏掉会编译失败
实例化对象时括号不是必须的,但影响语义
写 MyClass obj; 和 MyClass obj(); 看起来差不多,但后者在 C++ 中会被解析为「函数声明」——声明一个叫 obj、无参数、返回 MyClass 类型的函数。这不是你想要的对象。
这种歧义叫「最令人烦恼的解析(most vexing parse)」,尤其在带参数构造时更隐蔽:
立即学习“C++免费学习笔记(深入)”;
MyClass obj(42); // OK:调用 MyClass(int)
MyClass obj(); // ❌ 是函数声明,不是对象
MyClass obj{}; // ✅ 推荐:统一用花括号初始化(C++11 起)
- 默认构造:用
MyClass obj;或MyClass obj{}; - 带参构造:优先用
MyClass obj{value};,避免括号歧义 - 动态分配对象要用
new MyClass{...},记得配对delete(或改用std::unique_ptr)
成员变量未初始化会导致未定义行为
类里的内置类型成员(如 int、double、指针)如果不显式初始化,在栈上创建对象时值是随机的;堆上用 new MyClass(无括号)也一样。读取它们会触发未定义行为,调试时可能偶尔“看起来正常”,但上线就崩。
正确做法是在构造函数初始化列表里赋初值:
class MyClass {
public:
int x;
double y;
MyClass() : x{0}, y{0.0} {} // ✅ 初始化列表
};
- 不要在构造函数体内用
x = 0;赋值——那是先调默认构造再赋值,效率低且对 const/引用成员无效 - 如果类有 const 成员或引用成员,初始化列表是唯一合法方式
- 初始化顺序严格按成员在类中声明的顺序,和初始化列表里写的顺序无关
头文件里定义函数可能引发 ODR 违规
如果你在头文件里写了带函数体的成员函数(比如 void print() { std::cout ),又在多个 .cpp 文件里包含这个头,链接时会报错:<code>multiple definition of MyClass::print()。
解决方法只有两个:
- 把函数体挪到 .cpp 文件里,头文件只留声明
- 或者明确加
inline关键字(C++17 起也可用constexpr或模板函数自动 inline)
哪怕函数只有一行,只要它出现在头文件里,就得考虑 inline —— 否则多文件编译基本过不了链接关。
类和对象看着简单,但初始化列表顺序、括号歧义、头文件函数定义这三处,最容易在改代码时悄悄埋雷。尤其是从其他语言转过来的人,常以为“写了就能跑”,结果卡在链接或运行时随机崩溃上。










