欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

C++ public、protected、private继承

程序员文章站 2022-06-01 11:55:40
...

1 、C++继承机制的相关知识点

继承机制,就是利用已有的数据类型来定义新的数据类型,新数据类型将拥有基类的成员。派生类可以从一个基类派生,也可以从多个基类派生。从一个基类派生的继承称为单继承;从多个基类派生的继承称为多继承。

单继承语法:

class <派生类名称>:<继承方式><基类名>
{
//派生类新定义成员
}; 

多继承语法:

class <派生类名>:<继承方式1><基类名1>,<继承方式2><基类名2>,......
{
//派生类新定义成员
}; 

2、继承方式可见性问题

所谓“可见性”指的是“基类成员对派生类的可见性”(也就是派生类成员函数是否访问基类成员),以及“基类成员对派生类对象的可见性”(也就是派生类对象是否可通过"."运算符访问基类成员)。
派生类通过继承,将基类的成员作为自己的一部分,但不同的继承方式导致基类的成员在派生类中具有不同的属性。我们首先使用下图表示,基类成员继承后将会在派生类中表现的访问属性:

C++ public、protected、private继承

上图是单继承的方式,也没有涉及派生再次派生的情况。但这两种情况都可以使用该图的逻辑进行推导。就像再次派生的情况,只要将派生类当做基类看待就可以了。

下面通过一个表格表示继承的可见性关系:

继承方式 public继承 protected继承 private继承
基类成员属性 public protected private public protected private public protected private
基类成员对其对象 可见 不可见 不可见 可见 不可见 不可见 可见 不可见 不可见
基类成员对派生类 可见 可见 不可见 可见 可见 不可见 可见 可见 不可见
基类成员对派生类对象 可见 不可见 不可见 不可见 不可见 不可见 不可见 不可见 不可见

看这个表,大家发现protected继承与private继承一模一样,当前的基类及子类的访问可见性确实没有区别,仔细查看上面的继承图可以发现,其实区别主要的区别在于继承之后子类的类型变化,如果protected继承基础上再次产生继承,在孙子辈当中仍然可见;但是private继承基础上再次产生继承,就在孙子辈当中不可见了。

总结:

1、基类当中定义的public类型,对其类对象可见;

2、基类当中定义的public及protected类型,无论哪种继承方式,在子类当中可见

3、只有基类当中定义的public类型子类对象可见

3 、访问案例 

3.1 通过子类对象直接访问基类成员

#include <iostream>
using namespace std;

class Animal
{
public:
    Animal(){}
    void eat(){cout << "eat\n";}
};

class Giraffe:private Animal
{
public:
    Giraffe(){}
    void StreNeck(double){cout << "strec neck\n";}
};

class Dog:protected Animal
{
public:
    Dog(){}

    void dMeaw(){cout <<"dmeaw\n";}
};

class Cat:public Animal
{
public:
    Cat(){}

    void Meaw(){cout <<"meaw\n";}
};

void func(Animal & a)
{
    a.eat(); //通过对象访问基类的成员函数
}

int main(int argc, char *argv[])
{
    Cat dao;
    Giraffe gir;
    Dog dog;
    func(dao); // 只有公有继承,才能使用子类对象访问父类的公有成员
    //func(gir);//error 'Animal' is an inaccessible base of 'Giraffe'
    //func(dog); //error 'Animal' is an inaccessible base of 'Dog'
    return 0;
}

上述代码中只有公有继承的Cat类对象才能成功的调用func函数实现对基类成员函数eat()的调用。

3.2 通过子类成员访问基类

#include <iostream>
using namespace std;

class Animal
{
public:
    Animal(){}
    void eat(){cout << "eat\n";}
};

class Giraffe:private Animal
{
public:
    Giraffe(){}
    void StreNeck(double){cout << "strec neck\n";}
    void take(){ eat();} // 私有继承的子类成员可访问父类的public及protected成员
};

void func(Giraffe & a)
{
    a.take(); //子类对象访问子类的公有成员函数
}

int main(int argc, char *argv[])
{
    Giraffe gir;
    func(gir); //调用func函数
    return 0;
}