核心结论回顾:初始化成员变量是最常用功能 。构造函数本质是对象诞生瞬间自动执行的函数,除了赋值,还可以做资源申请、打印日志、计数、打开文件等各类操作。
cpp
#include <iostream>
#include <string>
#include <fstream> // 文件操作头文件
using namespace std;
class MobilePhone
{
public:
// 构造函数:创建对象自动执行
MobilePhone(string brand, int storage, string fileName)
{
// 任务1:初始化当前对象的成员变量(基础操作)
m_brand = brand;
m_storage = storage;
// 任务2:打开文件(申请资源,不是变量赋值)
logFile.open(fileName, ios::app);
if(logFile.is_open())
{
cout << "【构造函数】日志文件打开成功" << endl;
logFile << "新手机:" << m_brand << " 存储:" << m_storage << "GB" << endl;
}
else
{
cout << "【构造函数】日志文件打开失败!" << endl;
}
// 任务3:全局计数统计
phoneCount++;
cout << "【构造函数】已生产手机总数:" << phoneCount << endl;
}
// 成员函数,打印手机信息
void showInfo()
{
cout << "手机品牌:" << m_brand << ",存储:" << m_storage << "GB" << endl;
}
// 静态函数,查看总产量
static void showTotal()
{
cout << "全部手机总产量:" << phoneCount << endl;
}
// 析构函数(提前了解:对象销毁时执行,关闭文件)
~MobilePhone()
{
if(logFile.is_open())
{
logFile.close();
cout << "【析构函数】文件已关闭" << endl;
}
}
private:
string m_brand;
int m_storage;
ofstream logFile; // 文件输出流对象,用来写日志
static int phoneCount;
};
// 静态成员变量,在类外部初始化
int MobilePhone::phoneCount = 0;
int main()
{
MobilePhone phone1("华为", 256, "phone_log.txt");
phone1.showInfo();
MobilePhone phone2("小米", 512, "phone_log.txt");
phone2.showInfo();
MobilePhone::showTotal();
return 0;
}
运行输出
cpp
【构造函数】日志文件打开成功
【构造函数】已生产手机总数:1
手机品牌:华为,存储:256GB
【构造函数】日志文件打开成功
【构造函数】已生产手机总数:2
手机品牌:小米,存储:512GB
全部手机总产量:2
【析构函数】文件已关闭
【析构函数】文件已关闭
一、类内部代码逐词逐句拆解
cpp
class MobilePhone
class:C++ 关键字,告诉编译器接下来定义一个类(图纸模板)。MobilePhone:类的名字,自定义图纸名称。{}:大括号划定类的代码范围,类结束末尾必须写};,分号不能丢。
cpp
public:
public 访问修饰符,代表下面的构造函数、成员函数对外公开,main 函数可以访问调用。
cpp
MobilePhone(string brand, int storage, string fileName)
{
m_brand = brand;
m_storage = storage;
logFile.open(fileName, ios::app);
if(logFile.is_open())
{
cout << "【构造函数】日志文件打开成功" << endl;
logFile << "新手机:" << m_brand << " 存储:" << m_storage << "GB" << endl;
}
else
{
cout << "【构造函数】日志文件打开失败!" << endl;
}
phoneCount++;
cout << "【构造函数】已生产手机总数:" << phoneCount << endl;
}
MobilePhone:构造函数名称,必须和类名完全一致,没有任何返回类型(不能写 void/int)。创建对象时自动调用。(string brand, int storage, string fileName):参数列表string brand:形参 brand,临时局部变量,接收传入手机品牌。int storage:形参 storage,临时局部变量,接收存储容量。string fileName:形参 fileName,临时局部变量,接收日志文件名字。
{}:构造函数函数体,对象诞生瞬间,大括号里面所有代码依次执行 。m_brand = brand;、m_storage = storage;:初始化当前对象的成员变量(最基础工作)logFile.open(fileName, ios::app);:打开日志文件,申请系统资源,不属于变量赋值 。ios::app代表追加写入,每次新增内容不覆盖旧内容。if(logFile.is_open()):判断文件是否成功打开。logFile << "新手机:"...:往文件里写入文本,把手机信息保存到磁盘。phoneCount++;:静态计数变量 + 1,统计一共创建多少台手机,属于统计逻辑。
cpp
void showInfo()
{
cout << "手机品牌:" << m_brand << ",存储:" << m_storage << "GB" << endl;
}
void:返回类型,函数执行完毕不返回数据。showInfo:普通成员函数,打印手机信息。():无参数,调用时不需要传入数据。
cpp
static void showTotal()
{
cout << "全部手机总产量:" << phoneCount << endl;
}
static:静态关键字,这个函数属于整个类,不属于单个手机对象。showTotal:静态成员函数,查看手机总数量。
cpp
~MobilePhone()
{
if(logFile.is_open())
{
logFile.close();
cout << "【析构函数】文件已关闭" << endl;
}
}
~MobilePhone:析构函数,名字是波浪号 + 类名。对象销毁的时候自动执行。logFile.close():关闭文件,释放系统资源。
配套理解:构造函数创建对象、申请资源 ;析构函数销毁对象、释放资源,成对使用。
cpp
private:
string m_brand;
int m_storage;
ofstream logFile;
static int phoneCount;
private:私有修饰符,这些变量只能在当前类内部的函数访问,main 不能直接读写。string m_brand;:成员变量,保存手机品牌。int m_storage;:成员变量,保存存储容量。ofstream logFile;:文件输出流对象,属于当前对象的成员,用来写日志。static int phoneCount;:静态成员变量,不属于单个对象,整个类共享这一个变量,用来统计手机总数。
cpp
int MobilePhone::phoneCount = 0;
:::作用域解析运算符,代表phoneCount属于MobilePhone类。- 静态成员变量必须写在类外面初始化,设置初始值 0。
二、main 函数逐词拆解,重点:MobilePhone phone1("华为", 256, "phone_log.txt");
cpp
MobilePhone phone1("华为", 256, "phone_log.txt");
-
MobilePhone:类名,使用 MobilePhone 这个图纸创建对象。 -
phone1:对象名,在内存开辟一块空间存放 phone1 手机对象。 -
("华为", 256, "phone_log.txt"):实参,传递给构造函数。"华为"传给 brand;256传给 storage;"phone_log.txt"传给 fileName
写完这一行,自动执行构造函数里面全部代码:赋值、打开文件、写入日志、计数 + 1。不需要手动调用构造函数。
-
;分号,语句结束标记。
cpp
phone1.showInfo();
phone1:对象名,代表操作 phone1 这个手机实例。.点号(成员访问运算符),读作 "的",访问对象内部成员。showInfo:成员函数名字。():函数调用标记,带括号代表执行函数内部代码。;语句结束。
含义:调用 phone1 的 showInfo 函数,打印手机信息。
cpp
MobilePhone phone2("小米", 512, "phone_log.txt");
phone2.showInfo();
- 创建全新独立对象 phone2,开辟新内存,和 phone1 互不干扰。
- 自动执行构造函数:初始化 phone2 变量,打开同一个日志文件追加写入,总数再加 1。
- 调用 showInfo 打印 phone2 信息。
cpp
MobilePhone::showTotal();
::作用域解析符,调用静态函数,查看全部手机总产量。
cpp
return 0;
main 函数执行结束,phone1、phone2 对象销毁,自动执行析构函数,关闭文件。
三、完整执行流程,一步一步
- 程序启动,先初始化静态变量
phoneCount = 0。 MobilePhone phone1("华为", 256, "phone_log.txt");① 在内存开辟 phone1 对象内存。 ② 自动执行构造函数:- m_brand = "华为",m_storage = 256;
- 打开日志文件;
- 向文件写入手机信息;
- phoneCount 从 0 变成 1,打印提示;
phone1.showInfo();,打印 phone1 信息。MobilePhone phone2("小米", 512, "phone_log.txt");① 开辟 phone2 对象内存; ② 自动执行构造函数:初始化变量、打开文件、写入日志,phoneCount 变成 2。phone2.showInfo();打印 phone2 信息。MobilePhone::showTotal();,打印总产量。return 0;,main 结束。 ① phone2 对象先销毁,自动调用析构函数,关闭 phone2 的文件; ② phone1 对象销毁,自动调用析构函数,关闭 phone1 的文件。
四、知识点总结
✅ 构造函数能干的事:
- 初始化对象的成员变量(最常用,入门教程只讲这个)
- 打开文件、网络连接、申请堆内存(资源申请)
- 打印日志、统计计数、创建子对象
核心本质:对象出生那一刻自动运行的函数,里面可以写任意合法 C++ 代码
❌ 限制:
- 没有返回值,不能 return 返回数据,仅允许单独
return;提前退出 - 不能手动调用构造函数,只有创建对象时编译器自动调用
- 不建议写非常耗时的操作(大文件读取、长时间网络等待),会阻塞程序