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

在 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++ 面向对象编程。

相关推荐
Setsuna_F_Seiei5 小时前
前端转型 Agent 开发 04 之 MCP 与 Skill(赋予 Agent 更广工作能力)
前端·agent
Niuguangshuo6 小时前
论文解读:CTC,端到端序列识别的开山之作
算法·语音识别
刘发财6 小时前
前端2秒生成500页矢量PDF,rust真的强到没朋友
前端·javascript·rust
讳疾忌医丶6 小时前
深度拆解 RocksDB 内核:基于 C++17 的 FIFO 调度状态机与温度阶梯自愈设计
java·c++·算法·架构
2401_868534787 小时前
OpenStack 架构全景:八个核心组件深度拆解
c++·需求分析
郑州光合科技余经理7 小时前
国际版外卖系统:税率字段怎么和订单主流程解耦
android·java·开发语言·前端·后端·php·ai编程
高亦真7 小时前
今天是学习嵌入式的第37天
linux·学习·算法
软件课代表CiCi7 小时前
运行库是什么?电脑缺运行库怎么办?c++运行库缺失修复全攻略
开发语言·c++·windows·电脑·dll修复·dll丢失·运行库
梦想平凡7 小时前
百游棋牌源代码开发搭建教程(十):隔离部署、备份恢复与双端验收
java·前端·javascript·数据库·源代码管理
蒸蒸yyyyzwd8 小时前
从面经中学到的三件事
c++·笔记