什么是构造函数?¶
想象一下,你买了一台新电脑,开机时系统会自动初始化一些基本设置(比如加载默认程序、检查硬件)。在C++中,构造函数就像对象的“开机程序”——当你用类创建一个对象时,构造函数会自动被调用,负责给对象的成员变量赋初始值,完成对象的“初始化”工作。
构造函数的语法规则¶
构造函数是类的特殊成员函数,有以下特点:
1. 函数名与类名完全相同(大小写敏感)。
2. 没有返回类型(连void也不行)。
3. 可以带参数(实现不同方式的初始化)。
4. 默认情况下,对象创建时自动调用。
示例:定义一个简单的Person类,包含name和age两个成员变量,用构造函数初始化它们。
#include <string>
using namespace std;
class Person {
public:
string name; // 成员变量:姓名
int age; // 成员变量:年龄
// 构造函数:初始化对象
Person() { // 默认构造函数(无参数)
name = "Unknown"; // 给name赋默认值
age = 0; // 给age赋默认值
}
Person(string n, int a) { // 带参数的构造函数(重载)
name = n;
age = a;
}
};
默认构造函数:无参数的初始化¶
如果类中没有定义任何构造函数,编译器会自动生成一个默认构造函数(无参数,且函数体为空)。但如果我们定义了带参数的构造函数,编译器就不会再生成默认构造函数了。
问题:如果只写了带参数的构造函数,直接用Person p;(无参数)创建对象会报错!
解决:手动定义默认构造函数,即使函数体为空:
class Person {
public:
string name;
int age;
// 手动定义默认构造函数(无参数)
Person() {
name = "Unknown";
age = 0;
}
// 带参数的构造函数(重载)
Person(string n, int a) {
name = n;
age = a;
}
};
带参数的构造函数:灵活初始化对象¶
通过构造函数的重载(参数列表不同),可以让对象以多种方式初始化:
// 1. 默认初始化(无参数)
Person p1; // 调用默认构造函数:name="Unknown", age=0
// 2. 带参数初始化
Person p2("Alice", 20); // 调用带参数构造函数:name="Alice", age=20
Person p3("Bob"); // 如果有带1个参数的构造函数(如 Person(string n)),则会调用
扩展:可以有多个构造函数,参数数量/类型不同即可:
class Person {
public:
string name;
int age;
// 1. 默认构造函数
Person() {
name = "Unknown";
age = 0;
}
// 2. 带1个参数(仅姓名)
Person(string n) {
name = n;
age = 18; // 年龄默认设为18
}
// 3. 带2个参数(姓名+年龄)
Person(string n, int a) {
name = n;
age = a;
}
};
// 使用示例:
Person p4("Charlie"); // name="Charlie", age=18
Person p5("David", 25); // name="David", age=25
构造函数的调用时机¶
当你用类名创建对象时,构造函数会自动调用,无需手动调用:
// 创建对象时,构造函数被自动触发
Person p6; // 调用默认构造函数
Person p7("Eve", 30); // 调用带参数构造函数
关键点:构造函数是“对象的初始化器”,对象创建后,构造函数执行完毕,对象才处于“可用状态”。
注意事项¶
-
不能被显式调用:构造函数不能像普通函数一样用
p1.Person()调用,必须通过对象创建时触发。 -
默认构造函数的必要性:如果类中定义了带参数的构造函数,务必手动定义默认构造函数,否则
Person p;会报错。 -
成员变量初始化方式:构造函数中给成员变量赋值,通常有两种方式:
- 直接赋值(如name = "Alice";)。
- 使用参数初始化列表(更高效,Person(string n, int a) : name(n), age(a) {})。
总结¶
构造函数是C++中初始化对象的关键工具,核心作用是在对象创建时自动为成员变量赋初始值。掌握以下几点即可快速上手:
- 构造函数名与类名相同,无返回类型。
- 可以定义多个构造函数(重载),参数不同实现不同初始化方式。
- 默认构造函数在无参数时自动调用,带参数构造函数需手动调用。
通过简单例子(如Person类),就能理解构造函数如何让对象“从无到有”并完成初始化。后续学习中,构造函数还会与继承、多态等特性结合,但打好基础是关键!