必备技能10.2:对基类成员的访问控制
正如我们在前面所讨论到的那样,当一个类继承了另外一个类后,基类的所有成员也都会变成派生类的成员。然而,在派生类中,基类成员的可访问性是由派生类继承基类的方式来决定的,也就是由继承的访问限定符来决定的。派生类继承基类时的访问限定符只能是public,private或者protected。当我们没有指定访问限定符的时候,如果基类是一个类,那么缺省的访问限定符就是private。如果基类是一个结构体,则缺省的访问限定符是public。下面,我们就来讨论一下public和private继承方式的区别。protected的继承方式我们将在下节中进行讨论。
当派生类以公有的(public)的方式继承基类的时候,基类的所有公有成员就会变成是派生类的公有成员。然而,基类的私有成员则永远会是基类的私有成员,派生类是不能访问的。例如,在下面的程序中,B的公有成员变成了D的共有成员,因此可以被程序的其它部分访问。
//演示公有继承
#include <iostream>
using namespace std;
class B
{
int i,j;
public:
void set( int a, int b )
{
i = a;
j = b;
}
void show()
{
cout << i << " " << j << "\n";
}
};
class D : public B
{
int k;
public:
D(int x)
{
k = x;
}
void showk()
{
cout << k << "\n";
// i = 10 ; //错误!i在B类中是私有的成员,派生类是不能访问的。
}
};
int main()
{
D ob(3);
ob.set(1,2); //访问基类的共有成员
ob.show();//访问基类的共有成员
ob.showk();//访问派生类的共有成员
return 0;
}
既然set()和show()函数在基类B中都是公有的,因此他们是可以在main()函数中D类的对象上被调用的。i和j在基类B中都是私有的,这是下面的代码行
// i = 10 ; //错误!i在B类中是私有的成员,派生类是不能访问的。
被注释掉的原因。D类是不能访问B的私有成员的。
和公有继承想对应的就是私有继承。当以私有的方式继承基类的的时候,基类中所有的公有成员都在派生类中变成了私有成员。例如,下面的程序不能成功编译,就是因为set()和show()现在对于D类来说都是私有的,因此不能在main()函数中被调用。
//演示私有的继承方式,改程序不能被成功编译
#include <iostream>
using namespace std;
class B
{
int i,j;
public:
void set( int a, int b )
{
i = a;
j = b;
}
void show()
{
cout << i << " " << j << "\n";
}
};
class D : private B
{
int k;
public:
D(int x)
{
k = x;
}
void showk()
{
cout << k << "\n";
// i = 10 ; //错误!i在B类中是私有的成员,派生类是不能访问的。
}
};
int main()
{
D ob(3);
ob.set(1,2); //访问基类的共有成员
ob.show();//访问基类的共有成员
ob.showk();//访问派生类的共有成员
return 0;
}
小结:当基类以private的方式被继承的时候,其所有的共有成员都变成了派生类的私有成员。这就意味着,它们可以被派生类的成员调用,但是不能被程序的其它部分调用。
专家答疑
问:我知道在Java编程中使用父类和子类概念,这两个概念在C++中有什么含义?
答:Java中的父类就是C++中的基类。Java中的子类就是C++中的派生类。通常我们在这两个语言中都能听到这两种术语。但是在本书中,我们将使用标准的C++术语。另外,在C#中也是使用基类和派生类的术语。