关于C++中公有继承、私有继承、保护继承的讨论

一、文章来由

简单明了的理由,老生常谈但是没真正解决的问题,想搞清楚这个问题。

二、冗长的定义

我们先来看看这些冗长的定义:

公有继承:

当类的继承方式为公有继承时,基类的公有成员和保护成员的访问属性在派生类中不变,而基类的私有成员不可直接访问。也就是说基类的公有成员保护成员被继承到派生类中访问属性不变,仍作为派生类的公有成员和保护成员,派生类的其他成员可以直接访问它们。在类族之外只能通过派生类的对象访问从基类继承的公有成员。

私有继承:

当类的继承方式为私有继承时,基类中的公有成员和保护成员都以私有成员的身份出现在派生类中,而基类的私有成员在派生类中不可直接访问。也就是说基类的公有成员和保护成员被继承后作为派生类的私有成员,派生类的其他成员可以直接访问它们,但是在类族外部通过派生类的对象无法直接访问它们。无论是派生类的 成员还是通过派生类的对象,都无法直接访问从基类继承的私有成员。

保护继承:

保护继承中,基类的公有成员和保护成员都以保护成员的身份出现在派生类中,而基类的私有成员变量不可直接访问。这样,派生类的其他成员就可以直接访问从基类继承来的公有和保护成员,但在类的外部通过派生类的对象无法直接访问它们,无论是派生类的成员还是派生类的对象都无法直接访问基类的私有成员。

三、归纳上面冗长的定义

看完冗长的定义了,其实并没有什么太大作用~~因为定义是独立而严谨的,本来有共性的东西,没有得到归纳和牵起联系
好,我们来做如下归纳:

公有继承:

1、四个字:保持原状

2、权限:
(1)派生类成员只能访问基类中的 public/protected 成员;
(2)派生类的对象只能访问基类中的public成员。(注意:派生类和派生类对象是不同的)

私有继承:

1、还是四个字:均变私有

2、权限:
(1)派生类成员也只能访问基类中的 public/protected 成员;
(2)派生类的对象不能访问基类中的任何的成员。

保护继承:

1、这次字多一点:公有、保护变保护

2、权限:
(1)派生类的成员只能访问基类中的 public/protected 成员;
(2)派生类的对象不能访问基类中的任何的成员。

共性:

1、私有最终都是私有,且不可访问的;
2、这就像一个权限大小包含、约束关系,仔细体会;
3、对象只有公有继承,可以访问 public 成员,其余的都是不能访问的;
4、三种继承,成员访问都是一样的,因为相当于基类成员被已相应的权限规则被copy到子类;
5、上面说的成员可以是:
(1)成员函数
(2)成员变量

发现还是有些太多吧,画张图就更明白了~~

//公有继承【不变】               成员访问    对象访问
public    -->  public              Y         Y
protected -->  protected           Y         N
private   -->  private             N         N

//私有继承                      成员访问    对象访问
public    -->  private             Y         N
protected -->  private             Y         N
private   -->  private             N         N

//保护继承                      成员访问    对象访问
public    -->  protected           Y         N
protected -->  protected           Y         N
private   -->  private             N         N

四、例子

什么东西最后都是要用实例说话的。

例1(针对成员函数):

下面是一道软件设计师考试题:

已知3个类O、P、Q,类O中定义了一个私有方法 F1、一个公有方法 F2 和一个保护的方法 F3;类P和类Q是类O的派生类,其继承方式如下所示:
(1)class P: protected O{…}
(2)class Q: public O{…}

关于方法F1的描述正确的是(B):
A、方法 F1 无法被访问
B、只有在 类O 内才能访问方法 F1
C、只有在 类P 内才能访问方法 F1
D、只有在 类Q 内才能访问方法 F1

关于方法 F2 的描述正确的是(A):【这题网上答案有是C的,个人觉得错了】
A、类 O、P、Q 的对象都可以访问方法 F2
B、类 P 和 Q 的对象都可以访问方法 F2
C、类 O 和 Q 的对象都可以访问方法 F2
D、只有在 类P 内才能访问方法 F2

关于方法 F3 的描述正确的是(B):
A、类O、P、Q的对象都可以访问方法 F3
B、类O、P、Q的对象都不可以访问方法 F3 【可以毫不犹豫选出】
C、类O和Q的对象都可以访问方法F3
D、类P和Q的对象都可以访问方法F3

然后根据上面的信息,编写如下代码:

/* 
* 
* funtion: 注意,如下被注释的代码,都是访问不到的
* 
* Date:2015-7-29
* 
*    Author: Bill Wang
*/

#include<iostream>
using namespace std;

//在类O中分别定义了三个不同访问类型的函数
class O{
public:
    void F2()
    {
        cout<<"this is O's public function F2"<<endl;
    }
private:
    void F1();
protected:
    void F3();
};

//类P保护继承于O
class P:protected O{
public:
    /*
    void test_F1()
    {
        F1();
    }
    */
    void test_F2()
    {
        F2();
    }
    void test_F3()
    {
        F3();
    }
};

//类Q公有继承于O
class Q:public O{
public:
    /*
    void test_F1()
    {
        F1();
    }
    */
    void test_F2()
    {
        F2();
    }
    void test_F3()
    {
        F3();
    }
};

//类R私有继承于O
class R:private O{
public:
    /*
    void test_F1()
    {
        F1();
    }
    */
    void test_F2()
    {
        F2();
    }
    void test_F3()
    {
        F3();
    }
};

//定义在类体内或体外都一样
void O::F1()
{
    cout<<"this is O's private function F1"<<endl;
}
void O::F3()
{
    cout<<"this is O's protected function F3"<<endl;
}

//主函数
int main()
{
    O o;
    P p; //保护继承
    Q q; //公有继承
    R r; //私有继承

    cout<<"O:"<<endl;
    //o.F1(); //私有方法
    o.F2(); //公有方法
    //o.F3(); //保护方法
    cout<<endl;

    //三种继承:成员访问情况一样

    cout<<"P:"<<endl;
//  p.test_F1(); //私有方法访问不到
    p.test_F2();
    p.test_F3();
    //p.F1();
    //p.F2();
    //p.F3();
    cout<<endl;

    cout<<"Q:"<<endl;
//  q.test_F1();
    q.test_F2();
    q.test_F3();
    //q.F1();
    q.F2();
    //q.F3();
    cout<<endl;

    cout<<"R:"<<endl;
//  r.test_F1();
    r.test_F2();
    r.test_F3();
    //r.F1();
    //r.F2();
    //r.F3();

    return 0;
}

运行结果如下:
这里写图片描述
完全印证了上面的题目和图表~~

例2(针对成员变量):

是一样的,详见代码

#include<iostream>
using namespace std;

class A       //父类
{
private:
    int privatedateA;
protected:
    int protecteddateA;
public:
    int publicdateA;
};

class B :public A      //公有继承
{
public:
    void funct()
    {
        int b;
        //b=privatedateA;   //error:基类中私有成员在派生类中是不可见的
        b=protecteddateA; //ok:基类的保护成员在派生类中为保护成员
        b=publicdateA;    //ok:基类的公共成员在派生类中为公共成员
    }
};

class C :private A  //基类A的派生类C(私有继承)
{
public:
    void funct()
    {
        int c;
        //c=privatedateA;    //error:基类中私有成员在派生类中是不可见的
        c=protecteddateA;  //ok:基类的保护成员在派生类中为私有成员
        c=publicdateA;     //ok:基类的公共成员在派生类中为私有成员
    }
};

class D :protected A   //基类A的派生类D(保护继承)
{
public:
    void funct()
    {
        int d;
        //d=privatedateA;   //error:基类中私有成员在派生类中是不可见的
        d=protecteddateA; //ok:基类的保护成员在派生类中为保护成员
        d=publicdateA;    //ok:基类的公共成员在派生类中为保护成员
    }
};

int main()
{
    int a; 

    B objB;
    //a=objB.privatedateA;   //error:基类中私有成员在派生类中是不可见的,对对象不可见
    //a=objB.protecteddateA; //error:基类的保护成员在派生类中为保护成员,对对象不可见
    a=objB.publicdateA;    //ok:基类的公共成员在派生类中为公共成员,对对象可见

    C objC;
    //a=objC.privatedateA;   //error:基类中私有成员在派生类中是不可见的,对对象不可见
    //a=objC.protecteddateA; //error:基类的保护成员在派生类中为私有成员,对对象不可见
    //a=objC.publicdateA;    //error:基类的公共成员在派生类中为私有成员,对对象不可见

    D objD;
    //a=objD.privatedateA;   //error:基类中私有成员在派生类中是不可见的,对对象不可见
    //a=objD.protecteddateA; //error:基类的保护成员在派生类中为保护成员,对对象不可见
    //a=objD.publicdateA;    //error:基类的公共成员在派生类中为保护成员,对对象不可见

    return 0;
}

特别注意:
对于没有申明权限类型的成员(包括函数和变量)
(1)如果是在struct内默认定义是public
(2)如果是class里面则是private

我在写这段代码的时候发现了另一个问题,具体就不在这里赘述了,一篇文章的内容不要太丰富,不然容易迷失方向,在之后的文章中分析~~~

就写到这里~~~

—END—


参考文献

[1]http://wenku.baidu.com/link?url=IS4T_0J4TY4-dFymmwnlP_kx5zGnBNFMQw5N9iF-pejvd1QPRcF-tmZ7G7JhEpdriNxaHo9P5Yv2ctKCTvJDz0tlHGlStatEHX5xOMCmDS7

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值