前言
无论是在平时学习中还是还做项目之时,主要用到的继承都是 public 公有继承,因此,对protected private两者继承都不大了解!
今天,在看《Effective C++ 3e》 Item6 时,发现下面这个私有继承:
class Uncopyable
{
protected:
Uncopyable() {}
~Uncopyable() {} private:
Uncopyable(const Uncopyable&);
Uncopyable& operator=(const Uncopyable&);
}; class HomeForSale: private Uncopyable
{
...
};
在该例子当中,主要是想表现HomeForSale类对象不能拷贝、不能赋值,因此,需要将其copy constructor 与 copy assignment operator 定义为私有,不能被 类使用者拷贝和赋值。
那么,到底公有继承、私有继承、保护继承它们之间到底是怎么样的呢?下面我们详细分析一下:
概述
公有继承(public)、私有继承(private)、保护继承(protected)是常用的三种继承方式。
1. 公有继承(public)
公有继承的特点是基类的公有成员和保护成员作为派生类的成员时,它们都保持原有的状态,而基类的私有成员仍然是私有的,不能被这个派生类的子类所访问。
2. 私有继承(private)
私有继承的特点是基类的公有成员和保护成员都作为派生类的私有成员,并且不能被这个派生类的子类所访问。
3. 保护继承(protected)
保护继承的特点是基类的所有公有成员和保护成员都成为派生类的保护成员,并且只能被它的派生类成员函数或友元访问,基类的私有成员仍然是私有的。
下面列出三种不同的继承方式的基类特性和派生类特性。
基类属性 |
public |
protected |
private |
After 公有继承 |
public |
protected |
不可见 |
After 私有继承 |
private |
private |
不可见 |
After 保护继承 |
protected |
protected |
不可见 |
结论:
- 基类成员对派生类都是:公有和保护的成员是可见的,私有的的成员是不可见的。
- 基类成员对派生类的对象来说:要看基类的成员在派生类中变成了什么类型的成员。如:私有继承时,基类的公有成员和私有成员都变成了派生类中的私有成员,因此对于派生类中的对象来说基类的公有成员和私有成员就是不可见的。
所以,在公有继承时,派生类的对象可以访问基类中的公有成员;派生类的成员函数可以访问基类中的公有成员和保护成员。
这里,一定要区分清楚派生类的对象和派生类中的成员函数对基类的访问是不同的。
最后,看下面代码,从而,验证上述理论:
#include<iostream>
using namespace std;
//////////////////////////////////////////////////////////////////////////
class A //父类
{
private:
int privatedataA;
protected:
int protecteddataA;
public:
int publicdataA;
}; //////////////////////////////////////////////////////////////////////////
class B :public A //基类A的派生类B(共有继承)
{
public:
void funct()
{
int b;
b = privatedataA; //error:基类中私有成员在派生类中是不可见的
b = protecteddataA; //ok:基类的保护成员在派生类中为保护成员
b = publicdataA; //ok:基类的公共成员在派生类中为公共成员
}
}; //////////////////////////////////////////////////////////////////////////
class C :private A //基类A的派生类C(私有继承)
{
public:
void funct()
{
int c;
c = privatedataA; //error:基类中私有成员在派生类中是不可见的
c = protecteddataA; //ok:基类的保护成员在派生类中为私有成员
c = publicdataA; //ok:基类的公共成员在派生类中为私有成员
}
}; /////////////////////////////////////////////////////////////////////////
class C1: public C
{
public:
void fun()
{
int c1;
c1 = protecteddataA; //error: 基类中私有成员在派生类中是不可见的
c1 = publicdataA; //error: 基类中私有成员在派生类中是不可见的
}
}; //////////////////////////////////////////////////////////////////////////
class D :protected A //基类A的派生类D(保护继承)
{
public:
void funct()
{
int d;
d=privatedataA; //error:基类中私有成员在派生类中是不可见的
d=protecteddataA; //ok:基类的保护成员在派生类中为保护成员
d=publicdataA; //ok:基类的公共成员在派生类中为保护成员
} }; //////////////////////////////////////////////////////////////////////////
class D1: public D
{
public:
void func()
{
int d1;
d1 = protecteddataA; //ok! 基类的保护成员在派生类中为保护成员
d1 = publicdataA; //ok! 基类的保护成员在派生类中为保护成员
}
}; //////////////////////////////////////////////////////////////////////////
int main()
{
int a; B objB;
a = objB.privatedataA; //error:基类中私有成员在派生类中是不可见的,对对象不可见
a = objB.protecteddataA; //error:基类的保护成员在派生类中为保护成员,对对象不可见
a = objB.publicdataA; //ok:基类的公共成员在派生类中为公共成员,对对象可见 C objC;
a = objC.privatedataA; //error:基类中私有成员在派生类中是不可见的,对对象不可见
a = objC.protecteddataA; //error:基类的保护成员在派生类中为私有成员,对对象不可见
a = objC.publicdataA; //error:基类的公共成员在派生类中为私有成员,对对象不可见 D objD;
a = objD.privatedataA; //error:基类中私有成员在派生类中是不可见的,对对象不可见
a = objD.protecteddataA; //error:基类的保护成员在派生类中为保护成员,对对象不可见
a = objD.publicdataA; //error:基类的公共成员在派生类中为保护成员,对对象不可见 return ;
}