C++基础知识:封装

       在C++看来,存在于现实世界或者虚拟世界的万事万物皆为对象,而对象可以通过其属性和行为进行描述,具有相同性质的对象组成类。而进一步在对类的处理方式方面,C++提出了封装概念。下面通过简单例子学习一下怎样对一个类进行封装。
一、关于封装
   1、所谓封装,其实现手法是将类(或对象)的属性或行为的实现过程隐藏起来,对外仅公开一些接口以便于类外与之联系,达到数据和操作数据的方法(函数)有机统一。
   2、对属性和行为是否隐藏是通过设置访问权限实现的:
   public:(公有)类内类外都可以访问(也就是不隐藏)
   protected:(保护)类内可以访问,类外不可以访问,但子类可以访问(有条件隐藏)
   private: (私有)类内可以访问,类外不可以访问,子类也不可访问(绝对隐藏)
   3、写代码时,比如写上一行public:,则在其后声明的所有属性、方法都是公有的,直到另外的权限设置出现,比如又写上了protected:,则权限变成了保护。
   4、这里还要附带说一下,在类(class)中默认的访问权限是private,也就是说如果希望在类外能够访问到类的某个属性,则必须在public:下声明这个属性,而对于结构体(struct)则与其相反,默认的权限是public,刚从C转到C++时容易忽略这个public。这里所说的类外是指不在类的作用域或者说访问时不在类的成员函数中,但也有特例,比如加友元。
    5、为数据安全起见,一般将成员属性设置为private,然后通过在类内设置public属性的成员函数,有控制的间接在类外访问类内私有成员属性,做到读写可控并可以对数据有效性做检查,这就是所谓的封装。
二、类封装之后类外可以调用的函数
   1、构造函数
        定义类时如果没写构造函数,系统会自动添加一个空构造函数,这个空构造函数不需手动调用,系统会自动调用。这里提到的构造函数,是指我们自己写的构造函数,包括有参的或无参的。它们的主要用途是给声明的类对象赋初值。对于无参构造函数,虽然是自己写的,但也不需自己主动调用,声明对象时系统会自动调用。有参构造一般使用括号法在声明类对象时调用。举例如下:
       无参构造函数举例:

  class Person { //定义一个人员类
  public:
    string m_Name; //姓名
    int m_Age; //年龄
    Person() { //构造函数的权限必须是公有的,否则类外无法调用
        m_Name = "张三";
        m_Age = 25;
    }
  };

  //调用
   Person p1; //声明类对象(此时系统调用了无参构造函数,完成赋初值)
   cout << p1.m_Name << " " << p1.m_Age << endl; //运行结果:张三 25

      上面无参构造给类对象所赋初值都是一样的,有些死板,有参构造更为灵活,再举一例:

  class Person {
  public:
    string m_Name; //姓名
    int m_Age; //年龄
    Person(string name="张三", int age = 25) { //这里形参后“=某值”是缺省值,当不写参数声明类对象时,则赋给类对象缺省值。括号内可以不写缺省值只写形参。
      this->m_Name = name; //this是指向类对象自身的指针,可以不写;当形参与属性名字相同时,this可用于区分
      this->m_Age = age;
    }
  };
  //调用时
  Person p2("李四",36); //使用括号法调用有参构造函数赋初值
  cout << p2.m_Name << " " << p2.m_Age << endl; //运行结果:李四 36

       无论是系统生成的空构造函数,还是自己写的无参或有参构造函数,它们只是在声明类对象时被调用一次。如果将已经完成赋初值的对象再次调用构造函数,如p2("王五",40),则会报错。因此,当希望多次为某个类对象的属性赋值或访问时,则需要使用普通成员函数进行。
   2、用于赋值或访问的普通成员函数
  一般用于赋值或访问的成员函数的名字都使用setXXX或getXXX的形式,一眼就能看出是赋值或是访问。用于赋值或访问的成员函数就是文章开始提到的所谓接口,既然是接口,类外应能调用这些函数,因此它们的访问权限是public:。
      举一个例子说明如何建立接口:

 //声明一个计算两个int值合计的类
  class sum {
  private:
    int num1; //属性值为私有,类外访问不到
    int num2;
  public:
    sum() { //利用构造函数为属性赋缺省值
        this->num1 = 0;
        this->num2 = 0;
    }
    void setNum(int num1, int num2) { //为私有属性赋值接口
        this->num1 = num1; //由于成员函数形参名字与类属性名字相同,故加this区分
        this->num2 = num2; 
    }
    int getNum() { //返回私有属性合计值接口
        return num1 + num2;
    }
  };
  //通过这个类的对象调用接口函数
    sum s;
    cout << s.getNum() << endl; //运行结果:0
    s.setNum(12, 23);
    cout << s.getNum() << endl; //运行结果:35
    s.setNum(45, 45);
    cout << s.getNum() << endl; //运行结果:90

       以上,就是一个简单的封装例子。sum类的两个属性num1、num2为私有,类外访问不到;但通过sum类对象的成员函数setNum()可以为这两个属性赋值,通过getNum()可以获得两个私有属性的合计值。这样,虽不知道这个类的内部具体代码,就可以方便地使用这个类进行计算。

你可能感兴趣的:(c++)