C++ 从入门到精通C++ 从入门到精通
首页
基础教程
进阶教程
实战项目
编程指南
首页
基础教程
进阶教程
实战项目
编程指南
  • 💪 进阶基础

    • 📚 C++ 进阶教程
    • 第8章 - 指针基础
    • 第9章 - 引用和动态内存
    • 第10章 - 结构体和枚举
    • 第11章 - 文件操作
    • 第12章 - 预处理器和命名空间
  • 🎯 面向对象编程

    • 第13章 - 类和对象基础
    • 第14章 - 构造函数和析构函数
    • 第15章 - 封装、继承、多态
    • 第16章 - 运算符重载
    • 第17章 - 模板基础
    • 第18章 - 异常处理
  • 📦 STL 标准模板库

    • 第19章 - Vector 和 String
    • 第20章 - 容器类
    • 第21章 - Map 和 Set
    • 第22章 - 算法和迭代器

第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;
}

🎯 小结

概念说明
构造函数创建对象时自动调用,用于初始化
析构函数销毁对象时自动调用,用于清理资源
构造函数重载可以有多个构造函数,参数不同
初始化列表更高效的初始化方式
默认构造函数无参构造函数

🚀 下一步

掌握了构造和析构函数,你已经能够创建更完善的类了!

下一章,我们要学习面向对象的三大特性:封装、继承、多态!

➡️ 第15章 - 封装、继承、多态

最近更新: 2025/12/26 17:25
Contributors: 王长安
Prev
第13章 - 类和对象基础
Next
第15章 - 封装、继承、多态