《类和对象》—— 构造函数与析构函数总结

在 C++ 面向对象编程中,类(Class)和对象(Object)是核心内容,而构造函数与析构函数则是类中最重要的两个特殊成员函数。它们负责对象的"出生"和"销毁",直接影响程序的资源管理和对象生命周期。

本文将系统整理本节课中关于构造函数与析构函数的核心知识点,并结合代码案例进行分析。


一、构造函数(Constructor)

1. 什么是构造函数

构造函数是一种特殊的成员函数,用于在对象创建时完成初始化工作。

特点:

  • 函数名与类名相同

  • 没有返回值

  • 对象创建时自动调用

  • 可以重载

基本语法

复制代码
class 类名
{
public:
    类名()
    {
        // 初始化代码
    }
};

2. 为什么需要构造函数

对象创建后,如果成员变量没有初始化,就会出现随机值。

例如:

复制代码
class Date
{
public:
    int _year;
    int _month;
    int _day;
};

int main()
{
    Date d;
    cout << d._year << endl;
}

此时输出的是随机值。

因此,需要构造函数对对象进行初始化。


二、构造函数的分类


1. 无参构造函数(默认构造)

复制代码
class Date
{
public:
    Date()
    {
        _year = 2025;
        _month = 5;
        _day = 11;
    }

private:
    int _year;
    int _month;
    int _day;
};

调用方式

复制代码
Date d1;

注意:

复制代码
Date d1();

这不是创建对象,而是函数声明。


2. 带参构造函数

可以在创建对象时直接传入数据。

复制代码
class Date
{
public:
    Date(int year, int month, int day)
    {
        _year = year;
        _month = month;
        _day = day;
    }

private:
    int _year;
    int _month;
    int _day;
};

调用方式

复制代码
Date d1(2025, 5, 11);

3. 缺省参数构造函数

复制代码
class Date
{
public:
    Date(int year = 2025, int month = 1, int day = 1)
    {
        _year = year;
        _month = month;
        _day = day;
    }

private:
    int _year;
    int _month;
    int _day;
};

调用方式

复制代码
Date d1;
Date d2(2024, 10, 1);

三、构造函数的特性


1. 构造函数可以重载

复制代码
class Test
{
public:
    Test()
    {
        cout << "无参构造" << endl;
    }

    Test(int x)
    {
        cout << "带参构造" << endl;
    }
};

调用

复制代码
Test t1;
Test t2(10);

2. 对象创建时自动调用

复制代码
Date d1;

对象一创建:

  • 自动调用构造函数

  • 不需要手动调用


3. 如果没有写构造函数

编译器会自动生成默认构造函数。

复制代码
class A
{
private:
    int x;
};

系统会自动生成:

复制代码
A()
{
}

但是:

  • 内置类型不会初始化

  • 自定义类型会调用其默认构造


四、初始化列表


1. 什么是初始化列表

初始化列表是构造函数初始化成员变量的一种方式。

语法

复制代码
class Date
{
public:
    Date(int year, int month, int day)
        : _year(year)
        , _month(month)
        , _day(day)
    {
    }

private:
    int _year;
    int _month;
    int _day;
};

2. 为什么推荐使用初始化列表

因为:

  • 效率更高

  • 某些成员必须使用初始化列表

例如:

const成员

复制代码
const int _a;

引用成员

复制代码
int& _ref;

没有默认构造的对象成员

复制代码
class A
{
public:
    A(int a)
    {}
};

class B
{
public:
    B(int b)
        : _aa(b)
    {}

private:
    A _aa;
};

五、析构函数(Destructor)


1. 什么是析构函数

析构函数用于对象销毁时释放资源。

特点:

  • 函数名前加 ~

  • 无参数

  • 无返回值

  • 一个类只能有一个析构函数

  • 对象生命周期结束时自动调用


2. 基本语法

复制代码
class Test
{
public:
    ~Test()
    {
        cout << "析构函数调用" << endl;
    }
};

3. 析构函数的作用

主要用于:

  • 释放动态内存

  • 关闭文件

  • 释放系统资源

例如:

复制代码
class Stack
{
public:
    Stack(int n = 10)
    {
        _a = (int*)malloc(sizeof(int) * n);
        _capacity = n;
        _top = 0;
    }

    ~Stack()
    {
        free(_a);
        _a = nullptr;
        _capacity = 0;
        _top = 0;
    }

private:
    int* _a;
    int _top;
    int _capacity;
};

六、构造函数与析构函数的调用顺序


1. 单个对象

复制代码
Test t;

执行顺序:

复制代码
构造函数
析构函数

2. 多个对象

复制代码
Test t1;
Test t2;

执行顺序:

复制代码
构造 t1
构造 t2
析构 t2
析构 t1

规律:

  • 先构造的后析构

  • 类似栈结构(先进后出)


七、隐式生成的成员函数

C++ 编译器默认会生成:

  • 默认构造函数

  • 析构函数

  • 拷贝构造

  • 赋值运算符重载

其中:

默认析构函数

如果类中没有动态资源:

系统默认析构即可。

如果类中有动态申请资源:

必须自己写析构函数。


八、经典问题分析


1. 为什么析构函数不能重载?

因为对象销毁时:

编译器无法判断调用哪一个析构函数。

所以:

  • 一个类只能有一个析构函数

2. 构造函数能否是 void

不能。

构造函数没有返回值。

写成:

复制代码
void Test()

这已经是普通成员函数。


3. 构造函数可以被手动调用吗?

理论上可以:

复制代码
t.Test();

但不推荐。

因为对象初始化只应该进行一次。


九、总结

构造函数与析构函数是 C++ 类和对象中最核心的内容之一。

构造函数

负责:

  • 对象初始化

  • 建立对象状态

重点掌握:

  • 默认构造

  • 带参构造

  • 初始化列表

  • 构造函数重载


析构函数

负责:

  • 对象销毁

  • 资源释放

重点掌握:

  • 自动调用机制

  • 动态资源释放

  • 生命周期管理


十、学习建议

学习构造与析构时,建议重点理解:

  1. 对象生命周期

  2. 自动调用机制

  3. 初始化列表本质

  4. 动态内存管理

  5. RAII思想

因为后续:

  • 拷贝构造

  • 运算符重载

  • STL

  • 智能指针

都会建立在这些基础之上。


结语

构造函数和析构函数看似只是两个特殊函数,但它们本质上体现了 C++ 对"资源管理"和"对象生命周期"的核心思想。

真正理解它们之后,才能深入掌握 C++ 面向对象编程。

相关推荐
洛水水1 小时前
【力扣100题】19. 排序链表 | 归并排序详解
算法·leetcode·链表
csj501 小时前
前端基础之《React(8)—webpack简介-其他配置》
前端·react.js
凯瑟琳.奥古斯特1 小时前
丑数II C++三指针解法(力扣264)
数据结构·c++·算法·leetcode·职场和发展
YYYing.1 小时前
【C++项目之高并发内存池 (四)】三层缓存的空间回收流程详解
c++·笔记·缓存·高并发·内存池
小小de风呀1 小时前
de风——【从零开始学C++】(六):模板初阶
开发语言·c++
j_xxx404_1 小时前
力扣算法:用栈消消乐,巧解相邻重复与退格字符串
c++·算法·leetcode
恋猫de小郭1 小时前
AndroidX 将引入有全新 AppState ,用于管理 Compose 状态
android·前端·flutter
Hello.Reader1 小时前
算法基础(十一)—— 递归树如何看懂分治算法的运行时间
java·算法·排序算法
郝学胜-神的一滴1 小时前
二叉树与递归:解锁高级数据结构的编程内功心法
开发语言·数据结构·c++·算法·面试