C++中的构造函数是类的特殊成员函数,名称与类名相同,没有返回值,在创建类的对象时自动执行,主要作用是完成对象成员变量的初始化工作。编写构造函数时需要根据类的成员变量需求设计参数,同时合理使用初始化列表和默认构造函数,能让代码更高效规范。

普通构造函数的编写方式
普通构造函数可以带参数,参数用于接收初始化成员变量所需的值。构造函数的函数体内部可以写赋值逻辑,也可以通过初始化列表完成初始化。下面是一个简单的类构造函数示例:
#include <iostream>
#include <string>
using namespace std;
class Student {
private:
string name;
int age;
double score;
public:
// 带参数的普通构造函数
Student(string n, int a, double s) {
name = n;
age = a;
score = s;
}
void printInfo() {
cout << "姓名:" << name << ",年龄:" << age << ",分数:" << score << endl;
}
};
int main() {
Student stu("张三", 18, 92.5);
stu.printInfo();
return 0;
}
初始化列表的使用
初始化列表是构造函数定义中冒号后面的部分,用于在对象分配内存后直接初始化成员变量,而不是先默认初始化再赋值。对于const成员变量、引用类型成员变量,必须使用初始化列表完成初始化,同时初始化列表的效率比在函数体内赋值更高,因为避免了成员变量的额外构造和赋值操作。
初始化列表的语法是在构造函数参数列表后加冒号,然后依次写成员变量名加括号赋值,多个成员变量之间用逗号分隔:
#include <iostream>
#include <string>
using namespace std;
class Student {
private:
string name;
int age;
const int id; // const成员变量
int& refAge; // 引用类型成员变量
public:
// 使用初始化列表的构造函数
Student(string n, int a, int i, int& ra) : name(n), age(a), id(i), refAge(ra) {
// 函数体内不需要再对初始化列表中的成员赋值
}
void printInfo() {
cout << "姓名:" << name << ",年龄:" << age << ",ID:" << id << ",引用年龄:" << refAge << endl;
}
};
int main() {
int tempAge = 18;
Student stu("李四", 18, 1001, tempAge);
stu.printInfo();
return 0;
}
默认构造函数的编写
默认构造函数是不需要传入参数就能调用的构造函数,有两种情况:一是编译器自动生成的默认构造函数,当类中没有显式定义任何构造函数时,编译器会自动生成一个无参的默认构造函数,这个构造函数对内置类型成员变量不做初始化,对自定义类型成员变量调用其自身的默认构造函数;二是我们手动定义的默认构造函数,有两种形式,一种是无参构造函数,另一种是带默认参数值的构造函数。
注意:如果类中显式定义了其他带参数的构造函数,编译器就不会再自动生成默认构造函数,此时如果需要无参创建对象,就必须手动定义默认构造函数。
手动定义无参默认构造函数
#include <iostream>
#include <string>
using namespace std;
class Student {
private:
string name;
int age;
public:
// 手动定义的无参默认构造函数
Student() : name("未知"), age(0) {}
// 带参数的构造函数
Student(string n, int a) : name(n), age(a) {}
void printInfo() {
cout << "姓名:" << name << ",年龄:" << age << endl;
}
};
int main() {
Student stu1; // 调用无参默认构造函数
stu1.printInfo();
Student stu2("王五", 19); // 调用带参数构造函数
stu2.printInfo();
return 0;
}
带默认参数的默认构造函数
给构造函数的所有参数都设置默认值,也可以作为默认构造函数使用,此时创建对象时可以不传入参数,也可以传入部分或全部参数:
#include <iostream>
#include <string>
using namespace std;
class Student {
private:
string name;
int age;
public:
// 带默认参数的构造函数,也可作为默认构造函数
Student(string n = "未知", int a = 0) : name(n), age(a) {}
void printInfo() {
cout << "姓名:" << name << ",年龄:" << age << endl;
}
};
int main() {
Student stu1; // 不传参数,使用默认值
stu1.printInfo();
Student stu2("赵六"); // 只传第一个参数
stu2.printInfo();
Student stu3("孙七", 20); // 传全部参数
stu3.printInfo();
return 0;
}
构造函数编写注意事项
- 构造函数的名称必须和类名完全一致,包括大小写,没有返回值,也不能写void。
- 初始化列表中的成员变量初始化顺序和成员在类中声明的顺序一致,和初始化列表中的书写顺序无关。
- 一个类只能有一个默认构造函数,如果同时定义了无参构造函数和全默认参数的构造函数,会出现二义性错误。
- 如果类的成员变量是自定义类型,且该自定义类型没有默认构造函数,那么当前类的构造函数必须使用初始化列表完成该成员的初始化。