第14章 - 构造函数和析构函数
嗨,朋友!我是长安。
上一章我们学会了创建类和对象,但每次创建对象后都要手动初始化数据,很麻烦。
这一章,我们要学习构造函数和析构函数,让对象的创建和销毁自动化!
🏗️ 什么是构造函数?
构造函数是一个特殊的成员函数,在创建对象时自动调用,用于初始化对象。
特点
- ✅ 函数名与类名相同
- ✅ 没有返回类型(连void都没有)
- ✅ 可以重载(多个构造函数)
- ✅ 创建对象时自动调用
示例:无参构造函数
#include <iostream>
#include <string>
using namespace std;
class Student {
private:
string name;
int age;
public:
// 构造函数
Student() {
name = "未命名";
age = 0;
cout << "构造函数被调用!" << endl;
}
void display() {
cout << "姓名:" << name << ", 年龄:" << age << endl;
}
};
int main() {
Student stu; // 自动调用构造函数
stu.display();
return 0;
}
输出:
构造函数被调用!
姓名:未命名, 年龄:0
📝 带参数的构造函数
#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;
cout << "学生 " << name << " 创建成功!" << endl;
}
void display() {
cout << "姓名:" << name << ", 年龄:" << age << ", 成绩:" << score << endl;
}
};
int main() {
Student stu1("张三", 20, 95.5);
Student stu2("李四", 21, 88.0);
stu1.display();
stu2.display();
return 0;
}
🔄 构造函数重载
一个类可以有多个构造函数(参数不同)。
#include <iostream>
#include <string>
using namespace std;
class Rectangle {
private:
double length;
double width;
public:
// 无参构造
Rectangle() {
length = 1.0;
width = 1.0;
cout << "创建默认矩形" << endl;
}
// 一个参数(正方形)
Rectangle(double side) {
length = side;
width = side;
cout << "创建正方形" << endl;
}
// 两个参数(矩形)
Rectangle(double l, double w) {
length = l;
width = w;
cout << "创建矩形" << endl;
}
double getArea() {
return length * width;
}
};
int main() {
Rectangle r1; // 调用无参构造
Rectangle r2(5); // 调用一个参数的构造
Rectangle r3(10, 5); // 调用两个参数的构造
cout << "r1 面积:" << r1.getArea() << endl;
cout << "r2 面积:" << r2.getArea() << endl;
cout << "r3 面积:" << r3.getArea() << endl;
return 0;
}
🎯 初始化列表(推荐)
更高效的初始化方式:
class Student {
private:
string name;
int age;
double score;
public:
// 使用初始化列表
Student(string n, int a, double s) : name(n), age(a), score(s) {
cout << "学生对象创建完成" << endl;
}
};
💀 析构函数
析构函数在对象销毁时自动调用,用于清理资源。
特点
- ✅ 函数名是
~类名 - ✅ 没有参数,没有返回类型
- ✅ 每个类只能有一个析构函数
- ✅ 对象销毁时自动调用
#include <iostream>
using namespace std;
class Test {
private:
int id;
public:
Test(int i) : id(i) {
cout << "对象 " << id << " 创建" << endl;
}
~Test() {
cout << "对象 " << id << " 销毁" << endl;
}
};
int main() {
Test t1(1);
Test t2(2);
{
Test t3(3);
cout << "代码块结束..." << endl;
} // t3在这里销毁
cout << "main函数结束..." << endl;
return 0;
} // t1和t2在这里销毁
输出:
对象 1 创建
对象 2 创建
对象 3 创建
代码块结束...
对象 3 销毁
main函数结束...
对象 2 销毁
对象 1 销毁
🌟 实战案例
案例1:动态数组类
#include <iostream>
using namespace std;
class DynamicArray {
private:
int* data;
int size;
public:
// 构造函数
DynamicArray(int s) : size(s) {
data = new int[size];
cout << "创建大小为 " << size << " 的数组" << endl;
}
// 析构函数
~DynamicArray() {
delete[] data;
cout << "释放数组内存" << endl;
}
void set(int index, int value) {
if (index >= 0 && index < size) {
data[index] = value;
}
}
int get(int index) {
if (index >= 0 && index < size) {
return data[index];
}
return -1;
}
};
int main() {
DynamicArray arr(5);
for (int i = 0; i < 5; i++) {
arr.set(i, i * 10);
}
for (int i = 0; i < 5; i++) {
cout << arr.get(i) << " ";
}
cout << endl;
return 0;
} // 自动调用析构函数释放内存
案例2:银行账户完整版
#include <iostream>
#include <string>
using namespace std;
class BankAccount {
private:
string accountNumber;
string ownerName;
double balance;
public:
// 构造函数
BankAccount(string accNum, string owner, double initialBalance = 0)
: accountNumber(accNum), ownerName(owner), balance(initialBalance) {
cout << "账户 " << accountNumber << " 开户成功!" << endl;
}
// 析构函数
~BankAccount() {
cout << "账户 " << accountNumber << " 已注销" << endl;
}
void deposit(double amount) {
if (amount > 0) {
balance += amount;
cout << "存款 ¥" << amount << " 成功" << endl;
}
}
void withdraw(double amount) {
if (amount > 0 && amount <= balance) {
balance -= amount;
cout << "取款 ¥" << amount << " 成功" << endl;
} else {
cout << "余额不足!" << endl;
}
}
void display() {
cout << "\n===== 账户信息 =====" << endl;
cout << "账号:" << accountNumber << endl;
cout << "户主:" << ownerName << endl;
cout << "余额:¥" << balance << endl;
}
};
int main() {
BankAccount acc1("6222001234567890", "张三", 1000);
acc1.display();
acc1.deposit(500);
acc1.withdraw(300);
acc1.display();
return 0;
}
🎯 小结
| 概念 | 说明 |
|---|---|
| 构造函数 | 创建对象时自动调用,用于初始化 |
| 析构函数 | 销毁对象时自动调用,用于清理资源 |
| 构造函数重载 | 可以有多个构造函数,参数不同 |
| 初始化列表 | 更高效的初始化方式 |
| 默认构造函数 | 无参构造函数 |
🚀 下一步
掌握了构造和析构函数,你已经能够创建更完善的类了!
下一章,我们要学习面向对象的三大特性:封装、继承、多态!
