• 【C++入门】使用using重新定义继承的成员访问权限


    1、C++的权限管控和继承机制

    参考博客:《【C++入门】访问权限管控和继承机制详解》

    2、using重新定义成员继承时权限的场景

    (1)父类的public成员在private/protected继承后,在派生类中就成了private/protected权限而不是public权限,子类对象就不能再调用父类的public成员;
    (2)可能在父类中有100个public成员,在子类对象中只需要访问1个成员,其余99个成员都不需要访问,合适的做法是将100个父类的public成员以private/protected权限继承到子类,然后使用using关键字对需要访问的那一个父类public成员进行权限修改;

    3、using关键字使用方法

    3.1、示例代码

    #include 
    
    using namespace std;
    
    //父类
    class Animal
    {
    public:	
    	void speak(void);
    	
    };
    
    // 子类:protected权限继承Animal类
    class Dog : protected Animal
    {
    public:
    	
    	// 使用using关键字,强行将speak方法提升为public的访问权限,这就是权限打洞
    	using Animal::speak;
    
    	//void DogSpeak(void);	//在子类中新增函数实现调用父类的speak方法
    };
    
    
    void Animal::speak(void)
    {
    	cout << "Animal::speak" << endl;
    }
    
    #if 0
    void Dog::DogSpeak(void)
    {
    	this->speak();
    }
    #endif
    
    int main(void)
    {
    	Dog d;
    	d.speak();
    	
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    3.2、不使用using关键字结果分析

    main.cpp: In function ‘int main():
    main.cpp:42:10: error:void Animal::speak()’ is inaccessible within this context
      d.speak();
              ^
    main.cpp:27:6: note: declared here
     void Animal::speak(void)
          ^~~~~~
    main.cpp:42:10: error: ‘Animal’ is not an accessible base of ‘Dog’
      d.speak();
              ^
    Makefile:2: recipe for target 'all' failed
    make: *** [all] Error 1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    (1)编译时报错,显示Dog类的对象调用继承自父类的public成员speak时,没有权限;
    (2)有一种解决思路:在Dog中新定义Dog类自己的speak成员函数,在成员函数中去调用父类的speak成员函数;

    3.3、使用using关键字结果分析

    [root#]$ ./app 
    Animal::speak
    
    • 1
    • 2

    (1)using使用的格式:using 父类名::成员名字;
    (2)在子类中用using声明父类的成员后,speak成员在子类中从protected权限变为public权限;

    4、补充

    (1)using可以修改子类继承自父类的成员权限成public,但并不是所有继承自父类的成员都可以修改成public权限;
    (2) 如果成员在父类中本来就是private权限,那在子类中是无法使用using声明成public权限的;
    总结:using只是用来找回在继承中损失的权限,给部分成员开特例;

  • 相关阅读:
    轻量封装WebGPU渲染系统示例<12>- 基础3D对象实体(源码)
    474. 一和零
    腾讯正式开源 Spring Cloud Tencent,微服务套件又多一个选择
    SPA项目开发之首页导航+左侧菜单
    WorkTool企微机器人接入微信智能问答
    SpringBoot查询数据时报空指针异常
    2023-9-14 石子合并
    10:00面试,10:08就出来了,技术官问我K8s的核心概念!
    vue中时间控件
    【Java开发岗:项目篇】
  • 原文地址:https://blog.csdn.net/weixin_42031299/article/details/127579689