其实封装并不是编程中的一个思想,对于很多领域来说都是这样。对于电子器件来说,我们不关心其内部的结构,只在乎该器件能够实现什么样的功能。这样对于顾客来说,不用花时间研究内部的实现过程,而对于商家来说,也可以更好的保护它们的商业秘密。
而对于 C++ 来说也是这样,借由数据类型也可以实现封装。这样做的好处就是对外屏蔽了功能实现,对内开放了数据权限。
C++ 中的类和对象是经由 C 中的 struct 发展而来的,就好像 struct 是由数组发展而来的一样。因此我们可以先通过 struct 实现封装。
封装实现
#include <iostream>
using std::cout;
using std::endl;
typedef struct complex
{
int x;
int y;
}COMP;
void init(COMP &tmp,int x,int y)
{
tmp.x = x;
tmp.y = y;
}
COMP * operator +(COMP &tmp1,COMP &tmp2)
{
COMP *p = static_cast<COMP *>(new COMP);
p->x = tmp1.x + tmp2.x;
p->y = tmp1.y + tmp2.y;
return p;
}
COMP * operator -(COMP &tmp1,COMP &tmp2)
{
COMP *p = static_cast<COMP *>(new COMP);
p->x = tmp1.x - tmp2.x;
p->y = tmp1.y - tmp2.y;
return p;
}
COMP * operator *(COMP &tmp1,COMP &tmp2)
{
COMP *p = static_cast<COMP *>(new COMP);
p->x = tmp1.x*tmp2.x - tmp1.y*tmp2.y;
p->y = tmp1.x*tmp2.y + tmp1.y*tmp2.x;
return p;
}
int main()
{
COMP x,y;
init(x,1,2);
init(y,3,4);
cout<<x.x<<" "<<x.y<<endl;
cout<<y.x<<" "<<y.y<<endl;
COMP *z;
z = x+y;
cout<<z->x<<" "<<z->y<<endl;
delete z;
z = x-y;
cout<<z->x<<" "<<z->y<<endl;
delete z;
z = x*y;
cout<<z->x<<" "<<z->y<<endl;
delete z;
return 0;
}
结果为:
1 2
3 4
4 6
-2 -2
-5 10
上面的程序使用 struct 构建了类似复数的结果,并使用运算符重载实现了复数的加、减、乘运算。这样如果我们要进行复数的运算的话,可以直接使用 +-* 而不用具体关心内部的实现过程,因为我们在意的只是结果的正确性。
封装属性
封装的作用就像之前提到的那样:对外提供接口,对内提供数据。
虽然上边的函数在全局构建了接口函数,但是却也暴露了函数的实现过程,并且我们还能够在外部直接访问 struct 内的数据,这并不是我们想要的封装形式。这是由 struct 的性质决定的,在 C++ 中,提供了 class 的形式实现整个的封装过程。
struct 和 class 的不同在于,struct 中的数据和方法都是 public 的,而 class 中的数据和方法却是可以自定义的:
属性 | 内部 | 外部 |
public | yes | yes |
protected | yes | no |
private | yes | no |
protected 和 private 的区别在继承形式上。
class 封装
对于上边的 complex,如果使用 class 来封装:
#include <iostream>
using std::cout;
using std::endl;
class complex
{
public:
complex()
{
this->x = 0;
this->y = 0;
}
complex(int x, int y):x(x),y(y){}
complex * operator +(complex &tmp)
{
complex *p = static_cast<complex *>(new complex);
p->x = this->x + tmp.x;
p->y = this->y + tmp.y;
return p;
}
complex * operator -(complex &tmp)
{
complex *p = static_cast<complex *>(new complex);
p->x = this->x - tmp.x;
p->y = this->y - tmp.y;
return p;
}
complex * operator *(complex &tmp)
{
complex *p = static_cast<complex *>(new complex);
p->x = this->x*tmp.x - this->y*tmp.y;
p->y = this->x*tmp.y + this->y*tmp.x;
return p;
}
void display()
{
cout<<this->x<<" "<<this->y<<endl;
}
private:
int x;
int y;
};
int main()
{
complex x(1,2),y(3,4);
x.display();
y.display();
complex *z;
z = x+y;
z->display();
delete z;
z = x-y;
z->display();
delete z;
z = x*y;
z->display();
delete z;
return 0;
}
结果为:
1 2
3 4
4 6
-2 -2
-5 10
上边的程序使用 class 的概念封装了 complex 的形式,该形式下能够从外部调用对象的方法,但是却不能够从外部访问对象的数据,达到了封装的要求。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。