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

相关文章
|
6天前
|
Java C++
C++的学习之路:21、继承(2)
C++的学习之路:21、继承(2)
14 0
|
1月前
|
C++
8. C++继承
8. C++继承
23 0
|
1月前
|
安全 Java 编译器
C++:继承
C++:继承
32 0
|
1月前
|
安全 Java 编译器
C++:继承与派生
C++:继承与派生
|
3天前
|
设计模式 编译器 数据安全/隐私保护
C++ 多级继承与多重继承:代码组织与灵活性的平衡
C++的多级和多重继承允许类从多个基类继承,促进代码重用和组织。优点包括代码效率和灵活性,但复杂性、菱形继承问题(导致命名冲突和歧义)以及对基类修改的脆弱性是潜在缺点。建议使用接口继承或组合来避免菱形继承。访问控制规则遵循公有、私有和受保护继承的原则。在使用这些继承形式时,需谨慎权衡优缺点。
15 1
|
1月前
|
安全 编译器 程序员
C++中的继承
C++中的继承
22 2
|
1月前
|
算法 编译器 程序员
【C++ 泛型编程 入门篇】全面掌握C++元模板中的模板继承:模板继承深入指南和教程
【C++ 泛型编程 入门篇】全面掌握C++元模板中的模板继承:模板继承深入指南和教程
37 0
|
1月前
|
Java 编译器 C#
【C++ 继承的多样性】C++ 多继承与虚拟继承:探究核心原理与应用实践
【C++ 继承的多样性】C++ 多继承与虚拟继承:探究核心原理与应用实践
37 1
|
1月前
|
算法 编译器 程序员
【C++入门到精通】C++入门 —— 继承(基类、派生类和多态性)
继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能,这样产生新的类,称派生类。继承呈现了面向对象程序设计的层次结构,体现了由简单到复杂的认知过程。以前我们接触的复用都是函数复用,继承是类设计层次的复用。
81 0
|
1月前
|
设计模式 算法 数据库
【C++ 继承】C++继承解密:一步步引领您从基础到实战
【C++ 继承】C++继承解密:一步步引领您从基础到实战
64 0