授课语音

C++中的构造函数与析构函数

构造函数和析构函数是C++中非常重要的特性,用于对象的初始化和清理。理解它们的用法及规则是掌握C++面向对象编程的关键。


1. 构造函数(Constructor)

1.1 什么是构造函数

构造函数是类的一种特殊成员函数,用于在对象创建时初始化对象。它与类同名,且没有返回值。

1.2 构造函数的特点

  • 名称与类名相同。
  • 没有返回值(包括void)。
  • 在对象创建时自动调用。
  • 支持重载,可以定义多个构造函数。

1.3 构造函数的分类

  • 默认构造函数:没有参数或所有参数都有默认值的构造函数。
  • 有参构造函数:需要提供参数的构造函数。
  • 拷贝构造函数:以同类对象为参数,用于创建对象副本。
  • 委托构造函数:通过调用同类中另一个构造函数来完成初始化(C++11及以上支持)。

1.4 示例代码

#include <iostream>
#include <string>
using namespace std;

// 定义一个类
class Person {
private:
    string name;
    int age;

public:
    // 默认构造函数
    Person() {
        name = "Unknown";
        age = 0;
        cout << "调用默认构造函数" << endl;
    }

    // 有参构造函数
    Person(string n, int a) {
        name = n;
        age = a;
        cout << "调用有参构造函数" << endl;
    }

    // 拷贝构造函数
    Person(const Person &p) {
        name = p.name;
        age = p.age;
        cout << "调用拷贝构造函数" << endl;
    }

    // 显示信息的方法
    void display() const {
        cout << "姓名: " << name << ", 年龄: " << age << endl;
    }
};

int main() {
    Person p1;                       // 调用默认构造函数
    Person p2("Alice", 25);          // 调用有参构造函数
    Person p3 = p2;                  // 调用拷贝构造函数

    p1.display();
    p2.display();
    p3.display();

    return 0;
}

2. 析构函数(Destructor)

2.1 什么是析构函数

析构函数是类的一种特殊成员函数,用于在对象生命周期结束时清理资源。它与类同名,但在前面加一个波浪号~

2.2 析构函数的特点

  • 名称与类名相同,前加~
  • 没有参数和返回值。
  • 每个类最多只能有一个析构函数(不可重载)。
  • 在对象销毁时自动调用。

2.3 析构函数的作用

  • 释放动态分配的内存。
  • 关闭文件或释放其他系统资源。

2.4 示例代码

#include <iostream>
using namespace std;

class Resource {
private:
    int *data;

public:
    // 构造函数
    Resource(int value) {
        data = new int(value); // 动态分配内存
        cout << "资源已分配,值: " << *data << endl;
    }

    // 析构函数
    ~Resource() {
        delete data; // 释放动态分配的内存
        cout << "资源已释放" << endl;
    }

    // 显示数据的方法
    void display() const {
        cout << "数据值: " << *data << endl;
    }
};

int main() {
    Resource r(10); // 创建对象时调用构造函数
    r.display();    // 调用成员方法

    return 0; // 程序结束时,析构函数自动被调用
}

3. 构造函数与析构函数的使用规则

3.1 自动调用时机

  • 构造函数:在对象创建时调用。
  • 析构函数:在对象销毁时调用(如超出作用域或显式使用delete时)。

3.2 特殊注意事项

  • 如果类中未定义构造函数,编译器会生成一个默认构造函数。
  • 如果类中定义了析构函数,则需特别注意资源管理,避免内存泄漏。
  • 拷贝构造函数与赋值运算符需配合使用,遵循“资源管理三法则”(Rule of Three)。

3.3 代码示例:动态内存管理与规则

#include <iostream>
#include <cstring>
using namespace std;

class String {
private:
    char *str;

public:
    // 构造函数
    String(const char *s) {
        str = new char[strlen(s) + 1]; // 分配动态内存
        strcpy(str, s);
        cout << "调用构造函数,创建字符串: " << str << endl;
    }

    // 拷贝构造函数
    String(const String &s) {
        str = new char[strlen(s.str) + 1];
        strcpy(str, s.str);
        cout << "调用拷贝构造函数,复制字符串: " << str << endl;
    }

    // 析构函数
    ~String() {
        cout << "调用析构函数,释放字符串: " << str << endl;
        delete[] str; // 释放动态内存
    }

    // 显示字符串
    void display() const {
        cout << "字符串: " << str << endl;
    }
};

int main() {
    String s1("Hello");
    String s2 = s1; // 调用拷贝构造函数

    s1.display();
    s2.display();

    return 0; // 程序结束时,析构函数自动调用
}

4. 总结

  • 构造函数负责初始化对象,支持多种形式(默认、有参、拷贝、委托)。
  • 析构函数用于清理资源,避免资源泄漏。
  • 了解并遵循“资源管理三法则”,是编写健壮C++代码的重要前提。
去1:1私密咨询

系列课程: