核心结论回顾:初始化成员变量是最常用功能。构造函数本质是对象诞生瞬间自动执行的函数,除了赋值,还可以做资源申请、打印日志、计数、打开文件等各类操作。
#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; }运行输出
【构造函数】日志文件打开成功 【构造函数】已生产手机总数:1 手机品牌:华为,存储:256GB 【构造函数】日志文件打开成功 【构造函数】已生产手机总数:2 手机品牌:小米,存储:512GB 全部手机总产量:2 【析构函数】文件已关闭 【析构函数】文件已关闭一、类内部代码逐词逐句拆解
class MobilePhoneclass:C++ 关键字,告诉编译器接下来定义一个类(图纸模板)。MobilePhone:类的名字,自定义图纸名称。{}:大括号划定类的代码范围,类结束末尾必须写};,分号不能丢。
public:public访问修饰符,代表下面的构造函数、成员函数对外公开,main 函数可以访问调用。
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,统计一共创建多少台手机,属于统计逻辑。
void showInfo() { cout << "手机品牌:" << m_brand << ",存储:" << m_storage << "GB" << endl; }void:返回类型,函数执行完毕不返回数据。showInfo:普通成员函数,打印手机信息。():无参数,调用时不需要传入数据。
static void showTotal() { cout << "全部手机总产量:" << phoneCount << endl; }static:静态关键字,这个函数属于整个类,不属于单个手机对象。showTotal:静态成员函数,查看手机总数量。
~MobilePhone() { if(logFile.is_open()) { logFile.close(); cout << "【析构函数】文件已关闭" << endl; } }~MobilePhone:析构函数,名字是波浪号 + 类名。对象销毁的时候自动执行。logFile.close():关闭文件,释放系统资源。
配套理解:构造函数创建对象、申请资源;析构函数销毁对象、释放资源,成对使用。
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;:静态成员变量,不属于单个对象,整个类共享这一个变量,用来统计手机总数。
int MobilePhone::phoneCount = 0;:::作用域解析运算符,代表phoneCount属于MobilePhone类。- 静态成员变量必须写在类外面初始化,设置初始值 0。
二、main 函数逐词拆解,重点:MobilePhone phone1("华为", 256, "phone_log.txt");
MobilePhone phone1("华为", 256, "phone_log.txt");MobilePhone:类名,使用 MobilePhone 这个图纸创建对象。phone1:对象名,在内存开辟一块空间存放 phone1 手机对象。("华为", 256, "phone_log.txt"):实参,传递给构造函数。"华为"传给 brand;256传给 storage;"phone_log.txt"传给 fileName
写完这一行,自动执行构造函数里面全部代码:赋值、打开文件、写入日志、计数 + 1。不需要手动调用构造函数。
;分号,语句结束标记。
phone1.showInfo();phone1:对象名,代表操作 phone1 这个手机实例。.点号(成员访问运算符),读作 “的”,访问对象内部成员。showInfo:成员函数名字。():函数调用标记,带括号代表执行函数内部代码。;语句结束。
含义:调用 phone1 的 showInfo 函数,打印手机信息。
MobilePhone phone2("小米", 512, "phone_log.txt"); phone2.showInfo();- 创建全新独立对象 phone2,开辟新内存,和 phone1 互不干扰。
- 自动执行构造函数:初始化 phone2 变量,打开同一个日志文件追加写入,总数再加 1。
- 调用 showInfo 打印 phone2 信息。
MobilePhone::showTotal();::作用域解析符,调用静态函数,查看全部手机总产量。
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;提前退出 - 不能手动调用构造函数,只有创建对象时编译器自动调用
- 不建议写非常耗时的操作(大文件读取、长时间网络等待),会阻塞程序