目标:每一个单词、符号全部解释清楚,不留任何看不懂的地方例程:纯标准 C++,无 Qt,先吃透基础,后面再学 Qt 类
#include <iostream> #include <string> using namespace std; // ===================== 类定义开始 ===================== // 【class MobilePhone】这里逐个单词拆开讲 class MobilePhone { // public:访问修饰符 public: // 构造函数 MobilePhone(string brand, int storage) { m_brand = brand; m_storage = storage; } // 成员函数:打电话 void call(string number) { cout << m_brand << "手机,正在拨打号码:" << number << endl; } // 成员函数:打印手机信息 void showInfo() { cout << "手机品牌:" << m_brand << ",内存大小:" << m_storage << "GB" << endl; } // private:私有访问修饰符 private: string m_brand; // 成员变量:手机品牌 int m_storage; // 成员变量:手机存储容量 }; // ===================== 类定义结束 ===================== int main() { // 创建第一个对象 phone1 MobilePhone phone1("华为", 256); phone1.showInfo(); phone1.call("13800138000"); // 创建第二个对象 phone2 MobilePhone phone2("小米", 512); phone2.showInfo(); phone2.call("10086"); return 0; }运行输出:
手机品牌:华为,内存大小:256GB 华为手机,正在拨打号码:13800138000 手机品牌:小米,内存大小:512GB 小米手机,正在拨打号码:10086第一部分:类定义区域逐词解析class MobilePhone
class MobilePhoneclass关键字- 含义:英文就是 “类”。C++ 固定关键字
- 作用:告诉编译器:我现在要定义一个新的自定义类型(一张图纸)。
- 为什么必须写 class: 如果不写 class,编译器不知道你要定义 “类”。 不写 class,
MobilePhone只会被当成普通变量名,不会理解成包含属性 + 函数的图纸模板。
类比:class = 声明:下面这一大段是【图纸】
MobilePhone- 是类名,我们自己起的名字,代表这个图纸叫 “手机”。
- 命名习惯:首字母大写,多个单词驼峰写法(Mobile 手机 + Phone 电话)。
- 作用:以后要用这张图纸造对象的时候,就写这个名字。
- 注意:类名只是图纸名称,此时还没有真实手机实体,不占用存储数据的内存。
{ }大括号- 大括号里面,就是这个类(图纸)包含的全部内容:成员变量、成员函数。
- 左
{:图纸内容开始;右}:图纸内容结束。后面必须加分号;,新手最容易漏!
class MobilePhone { //图纸内容 }; // 这个分号千万不能丢!
public /private 讲解
public- 关键字:公开。
- 含义:下面写的函数 / 变量,外部代码(main 函数)可以直接访问、调用。
- 我们把成员函数写在 public,用来对外提供操作接口。
private- 关键字:私有。
- 含义:下面写的变量,只能在这个类内部的函数里面访问,main 函数不能直接读写。
- 一般把成员变量写在 private,保护数据,不让外部随便乱改(封装思想)。
构造函数:MobilePhone(string brand, int storage)
- 函数名和类名
MobilePhone完全一样,没有返回值。 - 触发时机:用这个类创建对象的一瞬间,自动调用。
- 作用:给新建出来的对象的成员变量赋初始值。
- 参数:
string brand:传入手机品牌(临时参数)int storage:传入存储大小(临时参数)
成员变量
string m_brand; int m_storage;m_brand:成员变量,保存这个手机对象的品牌。前缀m_是编码习惯,代表 member 成员。m_storage:成员变量,保存存储容量。
重点:每一个对象,都有属于自己独立的一份 m_brand、m_storage。phone1 的品牌和 phone2 互不干扰。
成员函数void showInfo()
void:返回值类型,代表这个函数执行完不返回任何数据。showInfo:函数名字,自己定义,功能是打印手机信息。():圆括号,存放函数的参数列表。这里括号是空的,代表调用这个函数不需要传入任何参数。{}:函数体,括号里面是这个函数要执行的代码。
void call(string number)call:函数名,打电话。(string number):调用 call 的时候,必须传一个字符串参数,这个参数在函数内部叫 number。
第二部分 main 函数区域逐词拆解(重点:phone2.showInfo();)
MobilePhone phone2("小米", 512); phone2.showInfo();第 1 行:MobilePhone phone2("小米", 512);
MobilePhone:类名(图纸),告诉编译器,我们要按照【MobilePhone 图纸】创建对象。phone2:对象名(实例名),自己起的名字。图纸是 MobilePhone;造出来的实体是 phone2。 phone2 在内存开辟一块空间,里面存放属于它自己的 m_brand="小米",m_storage=512。
("小米", 512):传给构造函数的参数,创建对象的时候自动调用构造函数。
第 2 行:phone2.showInfo();逐符号拆解!
phone2:对象名字,代表我们操作【phone2 这个手机实体】.点号(成员访问运算符)- 读作:的
- 作用:访问这个对象身上的成员(成员变量 / 成员函数)
- 逻辑:phone2 的 showInfo ()
- 规则:对象名。成员名字,固定语法。
showInfo:成员函数名,就是我们在类里面定义的打印信息的函数。()圆括号,为什么必须加?()是函数调用标记!- 写
showInfo不带括号:只是代表这个函数本身(函数地址),不会执行函数里面代码。 - 写
showInfo()带括号:代表调用、执行这个函数里面的代码。 - 如果函数需要参数,参数写在括号内;无参数,括号保留,里面空着。
;分号C++ 语句结束标记,代表这一行代码到此结束。
✅ 一句话总结
phone2.showInfo();找到 phone2 这个对象,访问它里面的 showInfo 成员函数,执行这个函数里面的代码。
对比:
phone2.call("10086");phone2 对象 . call 函数 ("10086 参数") ; 含义:调用 phone2 的 call 函数,把字符串 "10086" 传给 number 参数。
第三部分:完整执行流程,一步一步跟着走
程序从main()入口开始执行
MobilePhone phone1("华为", 256);- 使用 MobilePhone 图纸,在内存创建对象 phone1。
- 自动调用构造函数:brand 接收 "华为",storage 接收 256。
- 执行
m_brand = brand;→ phone1.m_brand = "华为" - 执行
m_storage = storage;→ phone1.m_storage = 256 - 构造函数执行结束,brand、storage 这两个临时参数变量销毁。
现在内存:phone1 对象,保存品牌华为、256G。
phone1.showInfo();- phone1:找到 phone1 对象
.:访问它的成员- showInfo ():执行 showInfo 函数内部代码
- 读取 phone1 自己的 m_brand、m_storage,打印文字。
- 函数执行完毕,返回 main。
phone1.call("13800138000");- 调用 phone1 的 call 函数,传入号码字符串。
- number 变量接收 "13800138000"
- 执行 cout 打印内容,函数结束,number 销毁。
MobilePhone phone2("小米", 512);- 创建全新独立对象 phone2,开辟新内存,和 phone1 互不影响。
- 构造函数执行,phone2.m_brand="小米",phone2.m_storage=512。
phone2.showInfo();- 找到 phone2 对象,执行它的 showInfo,读取 phone2 自己的属性打印。
phone2.call("10086");- 调用 phone2 的打电话函数,打印小米手机拨打 10086。
return 0;main 函数结束。- main 函数结束,phone1、phone2 这两个栈上对象自动销毁,内存回收。
第四部分 高频易错问题汇总
- 忘记类定义末尾的分号
};,直接编译报错!
class A { }; // 这里分号!showInfo和showInfo()的区别showInfo:只是函数名字,不执行代码showInfo():调用函数,执行代码
.点号只能跟对象名,用来访问对象的成员- private 里面的 m_brand,不能直接写
phone2.m_brand="苹果",编译报错,只能通过 public 成员函数读写。 - phone1、phone2 是两个独立对象,修改 phone2 的数据,phone1 完全不受影响。