关于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

时间: 2024-12-28 22:44:33

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

如何统计CS文件中公有类,私有类,受保护类的个数?

问题描述 1.如何统计CS文件中公有类,私有类,受保护类的个数?并同时统计出每个类的代码行数?2.publicclassA{publicclassB{}}这种情况只对A计数一次 解决方案 解决方案二:统计的前提是代码可以正确编译先用CSharpCodeProvider编译成Assembly然后反射出你要统计的类解决方案三:没有人知道吗??

浅谈js继承的实现及公有、私有、静态方法的书写_javascript技巧

今天没事的时候,研究了一下JS继承的实现,下面是html的源码: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>JS类的继承的实现</title> <script type="text/JavaScript"> //定义父类及公有.私有.静态属性及方法 function parent(){ var pname

继承 覆盖 多态-java私有方法可以继承吗

问题描述 java私有方法可以继承吗 私有的成员和方法可以在子类中被继承吗,如果不能为什么不能,求解详细点 解决方案 java继承中的"缺陷":"覆盖"私有方法java继承中的"缺陷":"覆盖"私有方法Java 继承与初始化."覆盖"私有方法 解决方案二: 首先说私有的成员和方法不能被子类继承,这是java语法规范强制规定,也是面向对象设计的原则. 其次,脱离具体的语言,从面向对象角度来看,用private

isempty-C# 接口的继承 私有成员

问题描述 C# 接口的继承 私有成员 public interface IIdGenerator { object GenerateId(object container, object document); bool IsEmpty(object id); } 下面这个继承上面的接口,接口中私有成员无法实现,总是报错,路过的给下帮助呗 public class rsIdGenerator:IIdGenerator { } 解决方案 接口没有私有属性,如果要在接口中发布属性,要这样 public

ExtJS4中使用mixins来实现多继承

 在ExtJS4中使用mixins来实现多继承,下面有个不错的示例,感兴趣的朋友可以参考下 在ExtJS4中使用mixins来实现多继承.具体例子代码如下:      代码如下: (function(){  Ext.onReady(function(){  Ext.define('say',{  canSay:function(){  alert("hello");  }  });  Ext.define('eat',{  caneat:function(){  alert("

如何在win7电脑中设置权限管理和权限继承?

  电脑中存放着很多的文件,其中有很多都是非常重要的,或者涉及到咱们的隐私,或者是工作中比较重要的不愿意让别人看到的文件,但是因为分类的关系,咱们又不能将它们放到一起,那么我们就需要一个一个的去设置访问权限吗?这样是不是太麻烦了呢?当然!如果大家看完今天的文章之后,应该就知道如何在win7 32位系统中设置权限管理和权限继承了吧! 1.首先,咱们随意的找到一个文件夹,然后右键点击,选择属性,在弹出来的属性窗口中,咱们将界面切换到安全这一栏,选择下方的高级设置. 2.这样就可以打开文件的"行政表格

对象-js中的方法继承和不使用继承添加方法的问题

问题描述 js中的方法继承和不使用继承添加方法的问题 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"&

java web-JavaWeb开发中如何实现HTML的模板继承?

问题描述 JavaWeb开发中如何实现HTML的模板继承? 在做javaweb的ssh学习(实际上只有spring和hibernate),之前做过thinkphp的corethink其中html可以实现继承,比如定义一个基本的站点风格,以后的html只要使用伪指令extends继承模板就能显示相同的风格,还可以重写,目前使用的freemarker的ftl,这个不能实现继承,只有一些宏定义,还比较难用,之前还找到了rythm这个java代码生产器,缺少必要的jar,而且也不知道如何集成到sh中,,

JavaScript中的公有、私有、特权和静态成员用法分析_javascript技巧

本文实例讲述了JavaScript中的公有.私有.特权和静态成员用法.分享给大家供大家参考.具体分析如下: 下面的内容是在<JavaScript.DOM高级程序设计>里面摘抄出来的,比较容易理解,特在此记录一下,便于入门Javascript的朋友们分享一下哈. 复制代码 代码如下: //构造函数 function myContructor(message){ this.myMessage = message; //私有属性 var separator = ' -'; var myOwner =