C++非继承时函数成员访问属性和类继承过程中的访问控制

 更新时间:2022年03月11日 09:20:37   作者:机器学习入坑者  
这篇文章主要介绍了C++非继承时函数成员访问属性和类继承过程中的访问控制,非继承时,protected成员和private成员没有任何区别,都是类内部可以直接访问它们、类外部的类对象不可访问它们、类内部的类对象可以访问它们,更多详细内容请参考下面相关资料

一、非继承时public、protected和private成员的访问属性

C++中保护成员使用protected进行声明,那么protected、public和private三者有什么区别呢?

先说结论:非继承时,protected成员和private成员没有任何区别,都是类内部可以直接访问它们、类外部的类对象不可访问它们、类内部的类对象可以访问它们;相比之下,public成员在类内部、类外部的类对象、类内部的类对象中都是可直接访问的。

下面定 义的Bird类:

class Bird {
public:
    Bird() { 
        eat();   // 正确,类内可以访问保护成员
    };
protected:
    void eat() { printf("Bird eating \n"); }
};

上述代码表明,类内是可以直接访问protected成员的,下面来看类外部的类对象:

int main() {
    Bird bird();
    bird.eat();  // 错误,protected成员类外部对象不可访问
}

上述代码表明,类外部类对象是不能直接访问protected成员的。

所以说,非继承时protected成员和private成员没有差别。它们真正展示出差异是在“基类和子类的继承”时,具体分析留在后面日志。

重点:上述分析强调了“类外部的类对象和类内部的类对象”是不同的(类内部类对象是指:Bird类的复制构造函数就使用Bird类对象的引用可以访问其私有成员和保护成员)。因此,才要特殊指明“类外部的类对象不能访问protected和private成员,类内部的类对象可以访问其protected和private成员”。

二、C++类继承过程中访问控制

在子类继承父类的过程中,子类可以指定以何种方式继承父类:public继承、protected继承和private继承,这个过程可以称为“访问控制”。

在学习访问控制之前,需要知道类含有三种成员public成员、protected成员、private成员。在非继承的情况下,这三种成员的访问属性是不同的:public成员在类内部和外部均可被直接访问;protected和private成员均可以被类内部和类内部的类对象访问,均不能被类外部的类对象访问。为了便于自己记忆,称这个规则为“非继承时三种成员的访问法则”
此知识点的复杂性在于继承方式有三种,每种继承方式又对应三种成员,所以一共是九种情况。

为此,采用表格形式记录如下:

上表中“子类吸收后”表示父类成员在子类中是何种身份(身份指:publicprotectedprivate),也就是说不同的继承类型使得父类成员在子类中的身份不同。

比如:在protected继承类型中,父类中的public成员对应在子类中为protected成员,此时子类内部(指成员函数和子类对象)可以访问该protected成员,但是子类外部的子类对象无法访问该成员。也就是说,通过protected类型的继承,该成员从父类中的public成员变为子类中的protected成员。

下面是public继承的例子,其中父类为Animal,子类为Duck:

class Animal {
public:
    Animal(int age_) { age = age_; printf("Init Animal \n"); 
    }

    void eat() { printf("Animal eating! \n"); }
protected:
    void run() { printf("Animal Running! \n"); }
private:
    int age=0;
    void showAge() { printf("Age is %d", age); }
};

父类Animal中分别定义了public类型的eat()函数、protected类型的run()函数、private类型的showAge()函数。子类可以通过选择不同的继承方式,改变这几个函数在子类中的访问属性:

class Duck:public Animal {
public:
    Duck(int age_) :Animal(age_) { 
        printf("init Duck! \n");
        run(); // 正确,子类内部可以访问基类public成员
        eat(); // 正确,子类内部可以访问基类protected成员
        showAge(); // 错误,子类内部不可访问基类的private成员
    };
};

总结:

按照自己目前的理解,不管继承方式为publicprotectedprivate三种中的哪一个,父类的private成员对应到子类中均“不可直接访问”。此外,子类不继承父类的构造函数和析构函数。

疑惑:

书中所说的“不可直接访问”,目前自己并不知道如何间接访问,猜测可能是采用 “get” 和 “set” 方式进行间接访问。

到此这篇关于C++非继承时函数成员访问属性和类继承过程中的访问控制的文章就介绍到这了,更多相关C++非继承和类继承访问内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C语言中无符号与有符号及相加问题

    C语言中无符号与有符号及相加问题

    这篇文章主要介绍了C语言中无符号与有符号及相加问题,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2018-08-08
  • 6个变态的C语言Hello World程序

    6个变态的C语言Hello World程序

    这篇文章主要介绍了6个变态的C语言Hello World程序,需要的朋友可以参考下
    2016-05-05
  • C语言如何实现一些算法或者函数你知道吗

    C语言如何实现一些算法或者函数你知道吗

    这篇文章主要为大家详细介绍了C语言实现一些算法或者函数,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-03-03
  • C++中cout输出中文信息乱码问题及解决

    C++中cout输出中文信息乱码问题及解决

    这篇文章主要介绍了C++中cout输出中文信息乱码问题及解决,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-11-11
  • 从零学习构造系统之bazel示例详解

    从零学习构造系统之bazel示例详解

    这篇文章主要为大家介绍了从零学习构造系统之bazel示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-02-02
  • C语言实现通讯录功能的流程与代码

    C语言实现通讯录功能的流程与代码

    通讯录是一个可以记录亲人、好友信息的工具,这篇文章主要为大家详细介绍了C语言实现通讯录管理,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-06-06
  • C++中std::vector的6种初始化方式

    C++中std::vector的6种初始化方式

    这篇文章主要介绍了C++中std::vector的6种初始化方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-08-08
  • Visual Studio 2022使用MinGW来编译调试C/C++程序的图文教程

    Visual Studio 2022使用MinGW来编译调试C/C++程序的图文教程

    这篇文章主要介绍了Visual Studio 2022使用MinGW来编译调试C/C++程序,以实例来简单介绍一下VS2022中如何使用MinGW来编译、调试C/C++程序,需要的朋友可以参考下
    2022-08-08
  • C++超详细讲解强制类型转换的用法

    C++超详细讲解强制类型转换的用法

    在C++语言中新增了四个关键字static_cast、const_cast、reinterpret_cast和dynamic_cast。这四个关键字都是用于类型转换的,类型转换(type cast),是高级语言的一个基本语法。它被实现为一个特殊的运算符,以小括号内加上类型名来表示,接下来让我们一起来详细了解
    2022-06-06
  • 基于Matlab实现多目标粘液霉菌算法的示例代码

    基于Matlab实现多目标粘液霉菌算法的示例代码

    多目标粘液霉菌算法(MOSMA),这是最近开发的粘液霉菌算法(SMA)的多目标变体,用于处理工业中的多目标优化问题。本文将用Matlab实现这一算法,需要的可以参考一下
    2022-05-05

最新评论