C++中的封装——类class

在C语言中可以使用struct(结构体)将相应的数据封装起来,统一使用,同样地在C++中也可以使用struct将相应的属性及方法封装起来,例如下面的程序:

#include <iostream>
using namespace std;
struct S{
    int e1, e2;
};

void f(const S& s){  //以引用的方式传递地址
    cout << s.e1 << " " << s.e2 << " ";
}

int main(){
    S s = {1, 2};  //定义一个S类,并赋值
    f(s);   //通过向函数f传递s的地址,以输出s中的两个属性
    S* z = &s; //定义一个指向s的指针z
    z->e1 = 3; //通过指针间接改变s中属性e1的值,注意,针对指针必须使用“->”符号,用来调用结构体中的成员
    (*z).e2 = 4; //通过指针指向的地址直接改变s中的属性e2的值,这里则要用"."调用,因为此处是*z
    f(s);  //再次输出
}

输出结果如下:

上面的程序中main函数中的第一行,初始化(赋值)一个结构体,在C++中称之为构建对象。在上面一个程序中,已经将对象s的所有属性(e1,e2)都放在了同一结构体(S)中,这相当于将所有具有同一性质的物质合并在了一起。例如下面的程序:

#include <cmath>  //在C++中有关复数和根运算的函数都在此头文件中
#include <iostream>
#include <iomanip>  //在C++中有关小数点精确的函数都在此头文件中
using namespace std;

struct Complex{
    double re;
    double im;  //结构体的属性为实部和虚部——对象为复数
    Complex mul(const Complex& z);

    double amount(){        //该方法用于计算对象复数的模
        cout << "amount() "; //用于确认该函数确实被调用了
        return sqrt(re * re + im * im);  //计算模的方法,sqrt为求平方根
    }
};

int main(){
    Complex a = {0, 0};
    bool valueChange = true;
    for(int i = 1; i <= 8; i++){
        double amount = a.amount();  //每循环一次就计算一次模,但是这一值确实每两次才改变一次,因为后面有if控制改变的条件
        cout << "|a| = " << showpoint << setprecision(2) << amount << "  ";  //输出模
        valueChange = !valueChange;
        if(valueChange){
            a.re = i;
            a.im = -i;
            cout << endl;
        }
    }
}

输出结果:

在上面的程序中,结构体s中的属性re,im即可以在其本身的方法中被读取使用,也可以在main函数中被直接修改,这样结构体中的数据可被任何一个函数调用或者修改,因此就会造成数据泄露,为了阻止这一情况的产生,C++提供了一些关键词用来保护数据的访问权限:

  1. private(私有):在这一关键词之后的数据(属性或者方法)均为对象私有的,只能在结构体内部进行修改或访问,其他函数或结构体没有访问权限。
  2. public(公共):在这一关键词之后的数据(属性或方法)均为公共的,在结构体外的任何函数都可对其访问或修改
  3. protected(保护):在这一关键词之后的数据均为受保护的类型,只有在该类或由该类派生出来的类中才有访问权限。例如:
#include <iostream>
#include <cmath>
#include <iomanip>
using namespace std;

struct Complex{
private:  //关键词private修饰,表示下面的re和im为结构体Complex的私有成员,只能在结构体中被访问或修改
    double re;
    double im;
public:  //关键词private修饰,表示下面的方法(value,amount,getReal,getImag)为公共成员,不仅能在能在结构体中被访问或修改,也可在main函数中被调用
    void value(double r, double i){
        re = r;
        im = i;
    }
    double amount(){
        return sqrt(re * re + im * im);
    }
    double getReal(){
        return re;
    }
    double getImag(){
        return im;
    }
};

int main(){
    Complex z;
    z.re = 3;   //产生编译错误
    z.im = 4;   //产生编译错误,此处re和im为结构体Complex的私有成员,在main函数中无访问和修改权限
    z.value(3, 4); //此处合法,方法value在结构体Complex,其拥有访问和修改im和re的权限,而value被关键词public所修饰,在main函数中可以访问或调用
    cout << z.re << " + " << z.im << "j"; //产生编译错误
    cout << z.getReal() << " + " << z.getImag() << "j";  //合法
    cout << endl;
    cout << "the amount of this complex number is: " << sqrt(z.re * z.re + z.im * z.im); //产生编译错误
    cout << "the amount of this complex number is: " << z.amount(); //合法
}

在C++中如果没有像上述程序中所示的声明,则结构体中所有的属性和方法均视为public。与此相对,C++还提供了另外一个关键词class(类),在class中,所有的属性和方法,如果没有特别声明,则均视为private。如下面程序:

struct S{
    int i;
};

class C{
    int j;
}

int main(){
    S s;
    s.i = 4;  //合法,结构体中的属性及方法默认为public
    C c;
    c.j = 4; //产生编译错误,类中的属性及方法默认为private
}

如果要将类中的属性及方法定义成public,则需要先声明。一般地,在一个类中,属性为private型,而访问,调用或修改其的方法为public类。这样在使用数据的同时也做到了对数据的保护。

如有错误,欢迎大家批评或指正!

猜你喜欢

转载自blog.csdn.net/WJ_SHI/article/details/81782643