之前关于继承的文章,我们总是将类的数据成员设置为公有的(public),这么做只是为了使例子更简单易懂。本文中,我们将讨论在继承的过程中,访问说明符所扮演的角色,同时也会讲到C++中的不同种类的继承。
关于这点,之前我们已经看过私有(private)和公有(public)访问说明符,这些说明符能够决定谁能访问类的成员。简单会议下,公有成员能在任何地方被访问。私有成员只能被同一个类的成员函数访问。请注意这意味着派生类不能访问基类的私有成员!
class Base
{
private:
int m_nPrivate; // can only be accessed by Base member functions (not derived classes)
public:
int m_nPublic; // can be accessed by anybody
};
当处理继承类时,事情变得有点复杂了。
首先,有第三种访问说明符:protected。请仔细看下面的代码:
class Base
{
public:
int m_nPublic; // can be accessed by anybody
private:
int m_nPrivate; // can only be accessed by Base member functions (but not derived classes)
protected:
int m_nProtected; // can be accessed by Base member functions, or derived classes.
};
class Derived: public Base
{
public:
Derived()
{
// Derived's access to Base members is not influenced by the type of inheritance used,
// so the following is always true:
m_nPublic = 1; // allowed: can access public base members from derived class
m_nPrivate = 2; // not allowed: can not access private base members from derived class
m_nProtected = 3; // allowed: can access protected base members from derived class
}
};
int main()
{
Base cBase;
cBase.m_nPublic = 1; // allowed: can access public members from outside class
cBase.m_nPrivate = 2; // not allowed: can not access private members from outside class
cBase.m_nProtected = 3; // not allowed: can not access protected members from outside class
}
第二点,当一个派生类继承于基类时,访问说明符可能会因为继承方式而改变。因为有3中继承方式:public,private,protected。
// Inherit from Base publicly
class Pub: public Base
{
};
// Inherit from Base privately
class Pri: private Base
{
};
// Inherit from Base protectedly
class Pro: protected Base
{
};
class Def: Base // Defaults to private inheritance
{
};
如果你不指定一种继承方式,那么C++默认指定为private继承。
这给了我们9种组合:3中成员访问说明符(public,private,protected),3中继承方式(public,private,protected)。
下面我将尽力解释它们之间的区别,不过在开始之前,我们的脑子里应该明白:有三种方法来访问成员
1.一个类总是能访问它自己的成员,不管访问说明符是什么。
2.公有访问类的成员要看类的访问说明符。
3.一个派生类访问从基类那继承来的成员要看基类的访问说明符。
通过下面的实例,我想大家能更加明白。
Public 继承
公有继承是使用的最广泛的继承方式。事实上,很少使用其他方式的继承,所有我们首要的任务就是理解这种继承方式。当公有继承一个基类,基类所有的成员将维持它们原有的访问说明符。私有成员还是私有,公有成员还是公有,受保护的成员还是受保护。
class Base
{
public:
int m_nPublic;
private:
int m_nPrivate;
protected:
int m_n