什么是良好的封装

封装、继承和多态是面向对象的三要素。

不良的封装会使程序变得难以开发和维护,严重的时候,甚至会破坏类的工作机制。

就如果一间房子,正常进出房间的通道就是门,房间内的东西被墙保护着,而如果你的墙被砸了一个洞,可以让人随意进出,那后果可想而知。

一个封装良好的类至少需要做到以下几点:

**1.尽可能地限制类和成员的可访问性**

尽可能地使用private,而不是public.

**2.不要公开暴露成员变量**

暴露成员变量会破坏类的封装性,从而限制对抽象的控制能力。

例如Point类

1 class Point

2 {

3 public:

4     int x;

5     int y;

6     long color;

7 }

这么做破坏了其封装性。使用者可以随意地使用类里的数据,而Point类却连成员变量何时被改变都无从知道。更严重的是,一旦需要改变该类的行为,将付出很大的代码。例如如果需要在 x<0时,color改变为红色。而下面的代码则可以轻易做到:

01 class Point

02 {

03 public:

04     int GetX();

05     void SetX(int x);

06

07     int GetY();

08     void SetY(int y);

09

10     long GetColor();

11 private:

12     int m_nx;

13     int m_ny;

14     long m_lcolor;

15 }

1 void Point::SetX(int x)

2 {

3     if(x < 0)

4         m_lcolor = 0xFF0000;

5

6     **m_n**x = x;

7 }

这样的封装才是合理且安全的,外部不知道,也不需要知道SetX内部是如何做的。

**3.避免把私用的成员函数放到类的接口中**

真正的封装,外部根本看不到任何实现细节。然而,C++等某些语言将某些细节放到了接口之中。如上面提到的Point类,虽然成员变量无法在类外被访问到,但是程序员仍然可以知道这些变量,这一点实际上是违背了封装的原则(或者C++鼓励程序员查阅实现细节?)。在《*Effective C++*》的第34条里,提到了解决为类问题的一个惯用技法:把类的接口与类的实现分离开,类声明中包含一个指针,指向该类的实现。

01 class Point

02 {

03     public:

04         int GetX();

05         void SetX(int x);

06         int GetY();

07         void SetY(int y);

08     private:

09         PointImplementation* m_pImpl;

10 }

**4.避免使用友元类**

除非很必要的场合,一般情况下尽量避免使用友元类,它对封装会造成破坏,使代码量提升,并大大增加了维护的难度