阅读时长25分钟 | 关键词C、类、对象、构造函数、析构函数、this指针、静态成员、const成员引言前几篇文章我们一直在和过程式的代码打交道——函数、指针、数组。但从这一篇开始我们要换一种思维面向对象。面向对象不是一种语法而是一种组织代码的哲学——把数据和操作数据的方法打包在一起形成一个类就像现实世界中的车有颜色、速度这些属性也有加速、刹车这些行为。一、什么是类什么是对象类是自定义的数据类型描述了有一类事物是什么样的。对象是类的实例是具体的某一个。classDog{// 这是类定义了狗是什么样的public:std::string name;intage;voidbark(){std::coutname汪汪std::endl;}};intmain(){Dog myDog;// 这是对象一只具体的狗myDog.name旺财;myDog.age3;myDog.bark();// 输出旺财汪汪}概念类比C 关键词类蓝图/设计图纸class对象根据蓝图造出的具体实物类的变量二、访问控制public 和 private类的成员可以设置不同的访问权限这是面向对象封装性的核心classBankAccount{public:// 外部可以访问voiddeposit(doubleamount){balanceamount;}doublegetBalance()const{returnbalance;}private:// 只有类内部可以访问doublebalance0.0;};intmain(){BankAccount acc;acc.deposit(1000);std::coutacc.getBalance()std::endl;// 1000 ✅// acc.balance -100; // ❌ 编译错误private 成员无法直接访问}访问修饰符类内部派生类外部public✅✅✅private✅❌❌protected✅✅❌ 默认规则class默认是privatestruct默认是public。三、构造函数对象的出生证明构造函数在对象创建时自动调用负责初始化。名称与类名相同没有返回值。3.1 默认构造函数 vs 有参构造函数classCat{public:std::string name;intage;// 默认构造函数无参Cat():name(未知),age(0){std::cout一只猫诞生了std::endl;}// 有参构造函数Cat(conststd::stringn,inta):name(n),age(a){std::coutname 诞生了std::endl;}voidmeow()const{std::cout喵我是 nameage 岁std::endl;}};intmain(){Cat c1;// 调用默认构造函数Catc2(Tom,2);// 调用有参构造函数c1.meow();// 喵我是 未知0 岁c2.meow();// 喵我是 Tom2 岁}3.2 构造函数初始化列表初始化列表在:后面直接初始化成员比在函数体内赋值更高效——特别是对于 const 成员和引用成员必须使用初始化列表classMyClass{public:constintid;// const 成员必须用初始化列表intref;// 引用成员也必须用初始化列表intvalue;MyClass(inti,intr,intv):id(i),ref(r),value(v){// 主体可以留空}};3.3 析构函数对象消亡时的告别名称在类名前加~无参无返回值对象销毁时自动调用。常用于释放动态分配的资源classResourceHolder{private:int*data;public:ResourceHolder(){datanewint[10];std::cout资源已分配std::endl;}~ResourceHolder(){// 析构函数delete[]data;std::cout资源已释放std::endl;}};构造函数 vs 析构函数构造析构调用时机对象创建时对象销毁时名称ClassName(...)~ClassName()参数可有参可无参不能有参数数量可多个重载只能有一个四、隐藏的 this 指针每个非静态成员函数都有一个隐含的this指针指向调用该函数的当前对象classMyClass{public:intvalue;voidsetValue(intvalue){this-valuevalue;// this-value 是成员变量value 是参数}voidprint()const{// this 在 const 函数中类型为 const MyClass* conststd::coutthis-valuestd::endl;}};五、静态成员属于类本身不属于任何一个对象classMyClass{public:staticintcount;// 静态成员变量声明MyClass(){count;}// 每创建一个对象计数1staticvoidprintCount(){// 静态成员函数std::cout当前对象数countstd::endl;// std::cout value; // ❌ 静态函数不能访问非静态成员(没有 this)}};intMyClass::count0;// ⚠️ 静态成员变量必须在类外部定义初始化intmain(){MyClass::printCount();// 0 — 通过类名直接调用MyClass a,b,c;MyClass::printCount();// 3}静态成员访问方式有无 this 指针可否访问非静态成员静态变量类名::变量名或对象.变量名无关—静态函数类名::函数名()或对象.函数名()无❌六、const 成员不可修改的承诺classMyClass{public:constintid;// const 成员变量MyClass(inti):id(i){}// 只能用初始化列表赋值intgetValue()const{// const 成员函数// value 10; // ❌ 不能修改任何成员变量returnvalue;}private:intvalue0;};const 用于语法含义成员变量const int id;初始化后不能修改成员函数int get() const;承诺不修改对象状态对象const MyClass obj;只能调用 const 成员函数小结序号知识点一句话总结1类与对象类是蓝图对象是实物成员变量属性成员函数行为2访问控制public 对外开放private 内部使用protected 子类可见3构造函数对象创建时自动调用初始化列表优于函数体赋值4析构函数对象销毁时自动调用释放资源5this 指针指向当前对象的隐含指针区分同名成员与参数6静态成员属于类本身所有对象共享无 this 指针7const 成员变量不可改初始化列表赋值函数承诺不改状态下一篇文章我们将深入拷贝控制——浅拷贝的陷阱、深拷贝的实现、以及 C11 的智能指针初探。本文是「C 从基础到项目实战」系列的第 5 篇。关注我不错过后续更新。