在基于对象的程序设计中,通常类的提供者只有一个,但是类的用户有许多个提供者
设计,并且通常也会实现。类用户使用提供者提供的公有接口行为的分离,可通过将类分成公
有与私有访问级别而反映出来。
在继承机制下,有多个类的提供者。一个提供基类实现,可能还有一些派生类,另外一
个或多个提供者在继承层次的生命周期内提供派生类。这种行为也是一种实现行为。于类的
提供者经常但并不总是需要访问基类的实现。为了提供这种能力,同时还要防止对基类
实现的一般性访问。C++提供了另外一个访问级别保护protected ,级别在类的保护区
域内的数据成员和成员函数。不提供给一般的程序,只提供给派生类放在基类的私有区
域内的成员,只能供该类自己使用。派生类不能使用下面是修改过的IntArray 类
class IntArray {
public:
// 构造函数
explicit IntArray( int size = DefaultArraySize );
IntArray( int *array, int array_size );
IntArray( const IntArray &rhs );
// 虚拟析构函数
virtual ~IntArray() { delete [] ia; }
// 等于和不等于操作
bool operator==( const IntArray& ) const;
bool operator!=( const IntArray& ) const;
IntArray& operator=( const IntArray& );
int size() const { return _size; }
// 去掉了索引检查功能 . . .
virtual int& operator[](int index) { return ia[index]; }
virtual void sort();
virtual int min() const;
virtual int max() const;
virtual int find( int value ) const;
protected:
// 参见13.5 节的说明
static const int DefaultArraySize = 12;
void init( int sz, int *array );
int _size;
int *ia;
};
在面向对象与基于对象的设计中,指明一个类的成员是public 的准则没有变化,重新设
计的IntArray 类将被用作基类,它仍然把构造函数析构函数下标操作符min()和max()
等等声明为公有成员,这些成员继续提供公有接口,但现在接口不只为IntArray 类服务,同
时也为从它派生的整个继承层次服务。
非公有的成员到底该声明为protected 还是private? 类成员是新的设计准则。如果希望防
止派生类直接访问某个成员,我们就把该成员声明为基类的private成员,如果确信某个成员
提供了派生类,需要直接访问的操作或数据存储,而且通过这个成员派生类的实现会更有效
则我们把该成员声明为protected ,对于IntArray 类,我们已经将全部数据成员设置成protected,
也就是实际上允许后续派生的类访问IntArray 的实现细节。
为了把一个类设计成基类,要做的第二个设计考虑是找出类型相关的成员函数,并把这些成员函数标记virtual 虚拟的。
对于类型相关的成员函数,它的算法由特定的基类或派生类的行为或实现来决定。例如
对每种数组类型下标操作符的实现是不同的,所以我们将它声明为Virtual
等于不等于操作符和size()成员函数的实现对于其应用的数组类型来说是独立的。因此
不把它声明成Virtual。