C++类入门:从学生类到立方体类的实践
在C中类class是面向对象编程的核心它允许我们将数据属性和操作方法封装在一起。本文将通过多个代码示例逐步讲解C类的基本概念、权限控制、封装特性以及成员函数与全局函数的区别。所有代码均经过测试你可以直接复制运行观察输出结果。1. 第一个类学生类我们先从一个简单的Student类开始它包含姓名和学号两个属性以及显示信息和设置属性的方法。cpp#include iostream #include string using namespace std; class Student { public: // 成员属性 string m_Name; int m_Id; // 成员方法 void showStudent() { cout 姓名为 m_Name 学号为 m_Id endl; } void setName(string name) { m_Name name; } void setId(int Id) { m_Id Id; } }; int main() { Student s1; // 实例化对象 s1.setName(李一博); // 调用方法设置姓名 s1.setId(33556677); // 调用方法设置学号 s1.showStudent(); // 显示信息 return 0; }讲解class Student { ... };定义了一个名为Student的类。类中包含两个成员属性也叫成员变量string m_Name和int m_Id用于存储学生的姓名和学号。还包含三个成员函数也叫方法showStudent()用于输出信息setName()和setId()用于设置私有属性此处属性是公有的但通常我们会将属性设为私有通过公有方法访问。在main()函数中我们创建了一个Student类型的对象s1并通过点运算符.调用成员函数。注意这里将属性设为public是为了简化示例实际开发中更推荐将属性设为私有后面会讲到。2. 类的访问权限public、protected、privateC中类成员有三种访问权限public类内类外均可访问。protected类内可以访问类外不可访问但派生类可以访问。private类内可以访问类外不可访问派生类也不能访问。下面的代码演示了这三种权限的区别cpp#include iostream #include string using namespace std; class Student { public: string m_Name; // 公有类内外都可访问 protected: string m_Car; // 保护类内可访问类外不行 private: int m_Password; // 私有仅类内可访问 public: void func() { m_Name liyibo; m_Car 法拉利; // 类内可以访问protected成员 m_Password 123456; // 类内可以访问private成员 } }; int main() { Student s1; s1.m_Name LGN; // 正确public成员 // s1.m_Car 兰博基尼; // 错误protected成员类外不可访问 // s1.m_Password 56748; // 错误private成员类外不可访问 return 0; }讲解在类Student中我们分别用public、protected、private标记了三个成员。在func()成员函数内部可以访问所有权限的成员。在main()中只能访问公有成员m_Name尝试访问protected或private成员会导致编译错误。这种权限控制是C实现封装性的基础。3. 结构体与类的区别在C中struct和class非常相似唯一的区别是默认访问权限class默认成员是private。struct默认成员是public。下面通过例子验证cpp#include iostream using namespace std; class C1 { int m_a 100; // 默认private }; struct C2 { int m_C2A 236; // 默认public }; int main() { C1 c1; // c1.m_a 100; // 错误private不可访问 C2 c2; c2.m_C2A 269; // 正确public可访问 cout m_C2A的值为: c2.m_C2A endl; return 0; }讲解class C1中的成员m_a没有显式指定权限因此默认为private在main中无法直接访问。struct C2中的成员m_C2A默认为public可以直接访问。除了默认权限外struct和class在功能上完全等价。通常我们用struct表示简单的数据集合用class表示具有复杂行为的对象。4. 封装与访问控制私有成员的操作将成员属性设为私有并通过公有成员函数来访问是封装的体现。这样做可以控制数据的读写权限甚至进行数据验证。4.1 设置可读可写权限下面的Person类演示了如何控制不同属性的读写cpp#include iostream #include string using namespace std; class Person { public: // 设置名字可写 void SetName(string name) { m_Name name; } // 读取名字可读 string GetName() { return m_Name; } // 读取年龄只读 int GetAge() { return m_Age; } // 设置偶像只写 void SetIdol(string idol) { m_Idol idol; } private: string m_Name; // 可读可写 int m_Age 18; // 只读未提供Set方法 string m_Idol; // 只写未提供Get方法 }; int main() { Person P1; P1.SetName(liyibo); cout Your name is P1.GetName() endl; cout Your age is P1.GetAge() endl; // 只能读 P1.SetIdol(liqiling); // 只能写 // cout P1.GetIdol(); // 错误没有提供Get方法 return 0; }讲解我们将m_Name、m_Age、m_Idol全部设为私有外部无法直接访问。通过公有方法SetName/GetName使m_Name可读可写。m_Age只提供了GetAge因此是只读的注意它在类内被初始化为18。m_Idol只提供了SetIdol因此是只写的。这种设计使得我们可以灵活控制属性的访问同时隐藏内部实现细节。4.2 数据验证封装的好处之一是可以对输入数据进行验证。下面的代码在设置年龄时增加了合法性检查cpp#include iostream #include string using namespace std; class Person { public: void SetName(string name) { m_Name name; } string GetName() { return m_Name; } int GetAge() { return m_Age; } // 设置年龄并进行数据验证 void SetAge(int age) { if (age 0 || age 150) { cout 输入年龄错误请重新输入年龄 endl; return; } m_Age age; } void SetIdol(string idol) { m_Idol idol; } private: string m_Name; int m_Age 18; // 默认18 string m_Idol; }; int main() { Person P1; P1.SetName(liyibo); cout Your name is P1.GetName() endl; cout Your age is P1.GetAge() endl; P1.SetAge(165); // 年龄过大触发错误提示 // 但此时年龄仍然是18因为SetAge中验证失败后直接返回未修改m_Age P1.SetIdol(liqiling); return 0; }讲解SetAge(int age)中判断了年龄范围如果不在0~150之间则输出错误信息并返回不会修改m_Age。这样保证了数据的有效性避免了非法值进入对象内部。这是封装带来的重要优势可以在入口处统一控制数据合法性。5. 综合案例立方体类最后我们通过一个稍复杂的例子——立方体类来巩固所学知识并比较成员函数和全局函数实现相同功能的方式。cpp#include iostream using namespace std; class Cube { public: void setL(int l) { m_L l; } int getL() { return m_L; } void setW(int w) { m_W w; } int getW() { return m_W; } void setH(int h) { m_H h; } int getH() { return m_H; } // 计算表面积 int caculateS() { return 2 * (m_L * m_W m_L * m_H m_W * m_H); } // 计算体积 int caculateV() { return m_L * m_W * m_H; } // 成员函数判断两个立方体是否相等 bool isSameByClass(Cube c2) { return (m_L c2.getL() m_W c2.getW() m_H c2.getH()); } private: int m_L; // 长 int m_W; // 宽 int m_H; // 高 }; // 全局函数判断两个立方体是否相等 bool isSameCube(Cube c1, Cube c2) { return (c1.getL() c2.getL() c1.getW() c2.getW() c1.getH() c2.getH()); } int main() { Cube c1; c1.setL(10); c1.setW(10); c1.setH(10); cout c1的表面积为 c1.caculateS() endl; cout c1的体积为 c1.caculateV() endl; Cube c2; c2.setL(10); c2.setW(10); c2.setH(12); // 使用全局函数判断 bool ret1 isSameCube(c1, c2); if (ret1) cout 使用全局函数判断:c1和c2相等 endl; else cout 使用全局函数判断:c1和c2不相等 endl; // 使用成员函数判断 bool ret2 c1.isSameByClass(c2); if (ret2) cout 使用成员函数判断:c1和c2相等 endl; else cout 使用成员函数判断:c1和c2不相等 endl; return 0; }讲解Cube类封装了长、宽、高三个私有属性并通过公有set/get方法进行访问。提供了caculateS()和caculateV()分别计算表面积和体积。判断两个立方体是否相等有两种方式成员函数isSameByClass(Cube c2)当前对象this与传入的c2进行比较。全局函数isSameCube(Cube c1, Cube c2)接收两个Cube对象的引用进行比较。在main中创建两个立方体c1和c2分别调用两种函数输出结果。通过这个例子可以看到成员函数可以直接访问当前对象的私有成员如m_L而全局函数只能通过公有get方法获取数据体现了封装的统一性。注意成员函数中也可以直接访问c2的私有成员因为同属于一个类但为了代码清晰我们依然通过getL()等方式访问这样即使将来属性名改变也只需修改get函数内部。总结通过以上五个部分的代码示例我们逐步学习了C类的基础知识类的定义与对象实例化成员属性和成员函数。访问权限public、protected、private的区别。struct与class默认访问权限的差异。封装与数据控制通过公有接口操作私有成员并可添加数据验证。成员函数与全局函数实现相同功能时的不同写法。这些内容是C面向对象编程的基石熟练掌握后你就可以设计出结构清晰、易于维护的类了。希望本文对你有所帮助欢迎在评论区留言交流
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2418719.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!