当前位置:   article > 正文

浅谈C++|类的封装篇_c++类封装特性

c++类封装特性

引子:

C++认为万事万物皆为对象,对象有其属性行为

人可以作为对象,属性有姓名,年龄,身高,体重等,行为有行走,吃饭,唱歌等。

车也可以作为一个对象,属性有轮胎,方向盘,车灯等,行为有载人,放音乐等。

1.封装

1.1封装的意义

封装是是C++面向对象三大特性之一

封装的意义:

  (1)将属性和行为作为一个整体,表现生活中的事物。

  (2)将属性和行为加以权限控制

1.1.1封装意义一:

  在设计类的时候,属性和行为写在一起,表现事物。

语法:class 类名{  访问权限:属性 /  行为 };

实例:设置一个长方体类,并求其体积

代码:

  1. #include <iostream>
  2. using namespace std;
  3. class cuboid {
  4. public:
  5. int height;
  6. int weight;
  7. int length;
  8. int show_tiji() {
  9. return height * weight * length;
  10. }
  11. };
  12. int main() {
  13. cuboid a1;
  14. a1.height = 10;
  15. a1.weight = 10;
  16. a1.length = 90;
  17. cout << a1.show_tiji();
  18. return 0;
  19. }

 1.1.2封装的意义二

类在设计时,可以把属性和行为放在不同权限下,加以控制

访问权限有三种:

1.public        公有权限,类内可以访问,类外可以访问

2.protected   保护权限,类内可以访问,类外不可以访问

3.private       私有权限,类内可以访问,类外不可以访问

代码: 

  1. #include <iostream>
  2. using namespace std;
  3. class people {
  4. public:
  5. string name;
  6. protected:
  7. string hose;
  8. private:
  9. int m_Password;
  10. public:
  11. void fun() {
  12. name = "小明";
  13. hose = "别墅";
  14. m_Password = 12345;
  15. }
  16. };
  17. int main() {
  18. people a;
  19. a.fun();
  20. cout << a.name << endl;
  21. //cout << a.hose << endl; //报错
  22. //cout << a.m_Password << endl; //报错
  23. return 0;
  24. }

1.2struct和class的区别

1.2.1默认权限不同

权限分为成员访问权限和继承权限

默认成员权限:class是私有的,struct是公有的

默认继承权限:class是private,struct是public

默认成员权限代码: 

  1. #include <iostream>
  2. using namespace std;
  3. class people1 {
  4. int a;
  5. };
  6. struct people2 {
  7. int a;
  8. };
  9. int main() {
  10. people1 a1;
  11. people2 a2;
  12. //a1.a = 100; //报错
  13. a2.a = 100;
  14. return 0;
  15. }

默认继承权限代码: 

  1. #include <iostream>
  2. using namespace std;
  3. struct A {
  4. int m_a;
  5. };
  6. struct B :A {
  7. int m_b;
  8. };
  9. int main() {
  10. B b;
  11. b.m_a = 100;
  12. return 0;
  13. }

struct默认为公有继承;

  1. #include <iostream>
  2. using namespace std;
  3. class A {
  4. public:
  5. int m_a;
  6. };
  7. class B :A {
  8. public:
  9. int m_b;
  10. };
  11. int main() {
  12. B b;
  13. b.m_b = 100;
  14. //b.m_a = 100;
  15. return 0;
  16. }

class默认私有继承

1.2.2能否定义模板参数

class可以定义模板参数  template<class  T>,而没有template<struct T>

 代码:

  1. #include <iostream>
  2. using namespace std;
  3. //template< typename T, typename Y >
  4. template< class T >
  5. void Func(T& t,T& y)
  6. {
  7. T temp = t;
  8. t = y;
  9. y = temp;
  10. }
  11. int main() {
  12. int a = 10, b = 20;
  13. Func(a, b);
  14. cout << a << ' ' << b << endl;
  15. return 0;
  16. }

1.2.3 class和struct相互继承

 默认的继承属性取决于子类而不是基类

代码: 

  1. #include <iostream>
  2. using namespace std;
  3. class A {
  4. public:
  5. int m_A;
  6. };
  7. struct B:A {
  8. int m_B;
  9. };
  10. int main() {
  11. B b;
  12. b.m_A = 10;
  13. b.m_B = 20;
  14. cout << b.m_A <<' '<<b.m_B << endl;
  15. return 0;
  16. }

struct作为子类,默认公有继承

代码: 

  1. #include <iostream>
  2. using namespace std;
  3. struct A {
  4. int m_A;
  5. };
  6. class B:A {
  7. public:
  8. int m_B;
  9. };
  10. int main() {
  11. B b;
  12. //b.m_A = 10; 报错
  13. b.m_B = 20;
  14. cout<<b.m_B << endl;
  15. return 0;
  16. }

1.2.4{}赋初值的讨论

因为C++是对C的扩充,那么它就兼容过去C中struct的特性

  1. #include <iostream>
  2. using namespace std;
  3. struct A
  4. {
  5. char a1;
  6. int a2;
  7. double a3;
  8. };
  9. int main() {
  10. A a = { 'p', 7, 451.154 }; //定义时赋初值,在struct时没问题,在class时出错
  11. return 0;
  12. }

在struct中加入一个构造函数(或虚函数),struct也不能用{}赋值了,原因是以{}的方式来赋值,只是用一个初始化列表来对数据进行按顺序的初始化,如果上面写成A a = {‘p’,7};则a1,a2被初始化,而a3没有。这样简单的copy操作,只能发生在简单的数据结构上,而不应该放在对象上。加入一个构造函数或是一个虚函数会使strcut更体现出一种对象的特性,而是{}操作不再有效。因为加入这样的函数(构造和虚函数),使得类的内部结构发生了变化。而加入一个普通的成员函数呢?你会发现{}依旧可用。其实你可以将普通的函数理解成对数据结构的一种算法,这并不打破它数据结构的特性。
 

1.2.5总结 

  • 结构是实值类型(Value Types),而类则是引用类型(Reference Types)。
  • 结构使用栈存储(Stack Allocation),而类使用堆存储(Heap Allocation)。

值类型的变量直接存储数据,而引用类型的变量持有的是数据的引用,数据存储在数据堆中。
 

概念:class和struct的语法基本相同,从声明到使用,都很相似,但是struct的约束要比class多,理论上,struct能做到的class都能做到,但class能做到的stuct却不一定做的到
类型:struct是值类型,class是引用类型,因此它们具有所有值类型和引用类型之间的差异
效率:由于栈的执行效率要比堆的执行效率高,但是栈资源却很有限,不适合处理逻辑复杂的大对象,因此struct常用来处理作为基类型对待的小对象,而class来处理某个商业逻辑
关系:struct不仅能继承也能被继承 ,而且可以实现接口,不过Class可以完全扩展。内部结构有区别,struct只能添加带参的构造函数,不能使用abstract和protected等修饰符,不能初始化实例字段
 

1.2.6选用技巧

(1) 在表示诸如点、矩形等主要用来存储数据的轻量级对象时,首选struct

(2) 在表示数据量大、逻辑复杂的大对象时,首选class

(3) 在表现抽象和多级别的对象层次时,class是最佳选择 

1.3成员属性设置为私有化好处

1.3.1控制读写权限

可读可写权限,只读权限,只写权限

代码: 

  1. #include <iostream>
  2. using namespace std;
  3. class people {
  4. public:
  5. void get_name(string name_1) {
  6. name = name_1; //写权限
  7. }
  8. string show_name() {
  9. return name; //读权限
  10. }
  11. void get_mima(string mima1) {
  12. mima = mima1; //写权限
  13. }
  14. int show_age() { //读权限
  15. return age;
  16. }
  17. private:
  18. //可读,可写
  19. string name;
  20. //只读
  21. int age;
  22. //只写
  23. string mima;
  24. };
  25. int main() {
  26. people p;
  27. p.get_name("小明");
  28. cout << p.show_name() << endl;
  29. p.get_mima("56789");
  30. cout << p.show_age(); //没有设置,随机值
  31. return 0;
  32. }

 1.3.2写权限检测数据的有效性

 代码:

  1. #include <iostream>
  2. using namespace std;
  3. class people {
  4. public:
  5. void get_name(string name_1) {
  6. name = name_1; //写权限
  7. }
  8. string show_name() {
  9. return name; //读权限
  10. }
  11. void get_mima(string mima1) {
  12. if (mima1.size() < 3) {
  13. cout << "密码太短,无效!" << endl;
  14. return;
  15. }
  16. mima = mima1; //写权限
  17. }
  18. int show_age() { //读权限
  19. return age;
  20. }
  21. private:
  22. //可读,可写
  23. string name;
  24. //只读
  25. int age;
  26. //只写
  27. string mima;
  28. };
  29. int main() {
  30. people p;
  31. p.get_name("小明");
  32. cout << p.show_name() << endl;
  33. p.get_mima("59");
  34. cout << p.show_age(); //没有设置,随机值
  35. return 0;
  36. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/392681
推荐阅读
相关标签
  

闽ICP备14008679号