公有、私有、保护继承的区别

  • Post author:
  • Post category:其他

以下对几种继承方法作粗略简介(参考c++面向对象程序设计—杜茂康版)

一、公有继承:

(1)公有继承不改变基类成员在派生类中的访问权限。在公有继承方式下,基类中的public成员、private成员、protected成员在派生类中保持它们在基类中相同的访问权限。

(2)在派生类中定义的成员函数不能直接访问基类的私有成员,只能通过基类的public成员或protected成员访问它们。

例子:

<span style="font-size:18px;">#include<iostream>
using namespace std;
class A
{
	int x;
protected:
	int y;
	void setx(int temp){x=temp;}
public:
	int z;
	void setX(int temp){x=temp;}
};
class B:public A
{
public:
	void f()
	{
		x=1;     //error,无法直接对基类中的私有成员进行修改
		y=2;     //ok,可以对基类中的protected成员进行修改
		z=3;     //ok,可以对基类中的protected成员进行修改
		setx(1);  //ok,可以通过访问基类中的protected成员对基类中私有成员进行修改
		setX(1);  //ok,可以通过访问基类中的public成员对基类中私有成员进行修改
	}
};
void main()
{
	B ke;
	ke.x=1;     //error,不能被类外的外部函数访问.
	ke.y=2;     //error,不能被类外的外部函数访问.
	ke.z=3;     //ok,可以被类外函数访问.
}</span>

二.私有继承

(1)在private派生方式下,基类的公有成员和保护成员在派生类中都变成了private成员,不再是派生类的公有接口函数,不能被派生类的外部函数访问。

(2)在私有派生方式下,虽然基类的public和protected成员在派生类中都变成了private成员,但它们仍然有区别。派生类的成员函数不能直接访问基类的private成员,但可以直接访问基类的public和protected成员,并且通过它们访问基类本身的private成员。

例子:

<span style="font-size:18px;">#include<iostream>
using namespace std;
class A
{
	int x;
protected:
	int y;
	void setx(int temp){x=temp;}
public:
	int z;
	void setX(int temp){x=temp;}
};
class B:private A
{
protected:
	void f()
	{
		</span><pre name="code" class="cpp"><span style="font-size:18px;">                x=1;     //error,无法直接对基类中的私有成员进行修改
		y=2;     //ok,可以对基类中的protected成员进行修改
		z=3;     //ok,可以对基类中的protected成员进行修改
		setx(1);  //ok,可以通过访问基类中的protected成员对基类中私有成员进行修改
		setX(1);  //ok,可以通过访问基类中的public成员对基类中私有成员进行修改</span>

}};void main(){B ke;

<span style="font-size:18px;">        ke.x=1;     //error,不能被类外的外部函数访问.
	ke.y=2;     //error,不能被类外的外部函数访问.
	ke.z=3;     //error,不可以被类外函数访问.</span>

}


三. 保护继承

在保护继承方式下,基类的public成员在派生类中的访问权限将修改为protected权限,而基类的protected成员在派生类中仍为protected成员,基类的private成员在派生类中仍为private成员。

私有继承和保护继承继承的情况相同。

<span style="font-size:18px;">#include<iostream>
using namespace std;
class A
{
	int x;
protected:
	int y;
	void setx(int temp){x=temp;}
public:
	int z;
	void setX(int temp){x=temp;}
};
class B:protected A
{
public:
	void f()
	{
		x=1;     //error,无法直接对基类中的私有成员进行修改
		y=2;     //ok,可以对基类中的protected成员进行修改
		z=3;     //ok,可以对基类中的protected成员进行修改
		setx(1);  //ok,可以通过访问基类中的protected成员对基类中私有成员进行修改
		setX(1);  //ok,可以通过访问基类中的public成员对基类中私有成员进行修改
	}
};
void main()
{
	B ke;
	ke.x=1;     //error,不能被类外的外部函数访问.
	ke.y=2;     //error,不能被类外的外部函数访问.
	ke.z=3;     //error,不能被类外的外部函数访问.
}
</span>

而私有继承和保护继承两者的区别仅在于对派生类的成员而言,对基类成员有不同的可见性。

上述所说的可见性也就是可访问性。

关于可访问性还有另的一种说法。这种规则中,称派生类的对象对基类访问为水平访问,称派生类的派生类对基类的访问为垂直访问。

<span style="font-size:18px;">#include<iostream>
using namespace std;
class A
{
	int x;
protected:
	int y;
public:
	int z;
};
class B:protected A
{
public:
	void f()
	{
		x=1;     //error,无法直接对基类中的私有成员进行修改
		y=2;     //ok,可以对基类中的protected成员进行修改
		z=3;     //ok,可以对基类中的protected成员进行修改
	}
};
class C:protected B
{
public:
	void f1()
	{
		x=1;     //error,无法直接对基类中的私有成员进行修改
		y=2;     //error,可以对基类中的protected成员进行修改
		z=3;     //error,可以对基类中的protected成员进行修改
	}
};</span>

私有继承只能继承一次,以后的派生类都无法对其基类成员进行继续访问。

我们再来观察保护继承

<span style="font-size:18px;">#include<iostream>
using namespace std;
class A
{
	int x;
protected:
	int y;
public:
	int z;
};
class B:protected A
{
public:
	void f()
	{
		x=1;     //error,无法直接对基类中的私有成员进行修改
		y=2;     //ok,可以对基类中的protected成员进行修改
		z=3;     //ok,可以对基类中的protected成员进行修改
	}
};
class C:protected B
{
public:
	void f1()
	{
		x=1;     //error,无法直接对基类中的私有成员进行修改
		y=2;     //ok,可以对基类中的protected成员进行修改
		z=3;     //ok,可以对基类中的protected成员进行修改
	}
};
class D:protected C
{
public:
	void f1()
	{
		x=1;     //error,无法直接对基类中的私有成员进行修改
		y=2;     //ok,可以对基类中的protected成员进行修改
		z=3;     //ok,可以对基类中的protected成员进行修改
	}
};</span>

显然,派生类能继续对基类中的protected成员和public成员访问,可以继续继承下去,这就是私有继承和保护继承的最根本区别——垂直访问


版权声明:本文为u014137561原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。