C++的语法中通过在派生类中使用using声明可以忽略继承方式 , 而让派生类对于基类的私有和保护成员具有特殊的访问权限 , 甚至可以改变派生类对象对于基类成员的访问权限 .

个人认为这种语法很容易让别人对于自己的代码产生误解 , 应该尽量少用或不用 . 为防止自己忘记 , 下面记录一下个人的理解 .

引用之C++ Primer5 P546

通过在类的内部使用using声明语句 , 我们可以将该类的直接或间接基类中的任何可访问成员标记出来 (非私有成员) . using声明语句中名字的访问权限由该using声明语句之前的访问说明符来决定

白话文解释 : 在派生类的内部通过using声明语句 , 我们可以忽略继承方式 ,改变派生类中可访问的基类成员在派生类中的访问权限 .

通过using声明改变类的继承方式

文字可能不好理解 , 看代码实例更容易体会

 class Base
{
public:
int base_public;
protected:
int base_protect;
private:
int base_private;
}; class Derive :private Base
{
public:
using Base::base_public;
protected:
using Base::base_protect;
private:
//using Base::base_private; // error , 编译器报错 , 不可访问
};

代码示例中 , 派生类Derive通过private的方式继承了基类Base , 然而又通过using声明改变了基类成员的访问权限 ,

也就是说这段代码中 , 虽然表面上派生类是以private的方式继承了基类  ,而实际上派生类对于基类的访问权限就是public的方式 !

代码实例中可以看出在派生类中无法通过using声明来标记基类的私有成员 , 也验证了书中的话  .

由于继承的特性 , 基类的私有成员仍然会自动成为派生类的私有成员

然而这样的代码 , 很容易让人产生误解 .

通过using声明 , 做出一些不合常规的代码

using声明语句中名字的访问权限由该using声明语句之前的访问说明符来决定

通过这一特性 , 甚至可以改变基类成员在派生类中的访问权限 ! 同样通过一些代码来演示

 #pragma warning (disable:4996)
#include <iostream> class Base
{
public:
int base_public = ;
protected:
int base_protect = ;
private:
int base_private = ;
}; class Derive :private Base
{
public:
//在public作用域声明基类中的成员
using Base::base_public;
using Base::base_protect;
//using Base::base_private; // error , 编译器报错 , 不可访问
}; int main()
{
Derive test;
std::cout << "基类的公有成员: "<< test.base_public << std::endl;
std::cout << "基类的保护成员: " << test.base_protect << std::endl;
//std::cout << "基类的私有成员: " << test.base_private << std::endl; //error , 不可访问 system("pause");
return EXIT_SUCCESS;
}

代码中通过给基类的成员设定了默认初始值以便访问时显示 , 最终的运行结果如下

基类的公有成员:
基类的保护成员:
请按任意键继续. . .

代码中派生类继承时同样使用private的方式继承 , 然而我们把using声明放在了public权限下  , 由于 " using声明语句中名字的访问权限由该using声明语句之前的访问说明符来决定"

所以此时基类中的公有成员和保护成员都变成了派生类中的公有成员  , 也就是说通过using声明 , 我们通过私有继承的派生类 比 公有继承的访问权限反而更高  !

在main()函数中 派生类的对象可以访问基类的保护成员也验证了基类的保护成员在派生类中的访问权限已变成公有 .

也就是说通过这样的方式派生类对象可以访问基类的保护成员 , 而基类自己的对象却无法访问 .

需要注意的是通过派生类访问基类的保护成员时 , 编译器并不会给出智能提示 .

通过在类的内部使用using声明语句 , 我们可以将该类的直接或间接基类中的任何可访问成员标记出来 (只限于非私有成员) . using声明语句中名字的访问权限由该using声明语句之前的访问说明符来决定

通过using声明改变个别成员的可访问性的更多相关文章

  1. 《Effective Java》笔记 使类和成员的可访问性最小化

    类和接口 第13条 使类和成员的可访问性最小化 1.设计良好的模块会隐藏所有的实现细节,把它的API与实现清晰的隔离开来,模块之间只通过它们的API进行通信,一个模块不需要知道其他模块的内部工作情况: ...

  2. Effective Java:Ch4_Class:Item13_最小化类及其成员的可访问性

    要区别一个模块是否设计良好,最重要的因素是,对于其他模块而言该模块隐藏其内部数据和其他实现细节的程度.设计良好的模块应该隐藏所有实现细节,将API与其实现清晰地隔离开来.这样,模块之间通过他们的API ...

  3. Effective Java 第三版——15. 使类和成员的可访问性最小化

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  4. Effective Java --使类和成员的可访问性最小化

    尽可能地降低可访问性 接口和成员变量访问级别四种访问级别: 私有的(private) --- 只有在生命该成员的顶层类内部才可以访问 包级私有的(package-private) --- 缺省的&qu ...

  5. EffectiveJava(13)使类和成员的可访问性最小化

    1.为什么要使类和成员可访问性最小化 它可以有效地解除组成系统的各模块之间的耦合关系,使得这些模块可以独立的开发 测试 优化 使用 理解和修改.提高软件的可重用性 2.成员的访问级别 私有(priva ...

  6. C++入门经典-类成员的可访问性,继承后的可访问性

    1:关键字public.private.protected说明类成员是共有的.私有的,还是保护的.这3个关键字将类划分为3个区域,在public区域的类成员可以在类作用域外被访问,而private区域 ...

  7. Effective Java —— 使类和成员的可访问性最小化

    本文参考 本篇文章参考自<Effective Java>第三版第十五条"Minimize the accessibility of classes and members&quo ...

  8. .Net6种成员的可访问性

    CLR术语 C#术语 描述 Private private 成员只能由定义类型或任何嵌套类型访问 Family protected 成员只能由定义类型,任何嵌套类型或者不管在任何程序集中声明的派生类型 ...

  9. c# 类成员的可访问性

随机推荐

  1. Nim积的一种???的写法

    Nim积总不能一直打四次暴力吧! 用SG定理等东西,可以证明 \((N, \oplus, \otimes)\) 构成一个域.(证明很难,我不会) 其中 \(\oplus\) 为异或, \(x \oti ...

  2. 泛目录程序(莲花泛目录程序/黑帽SEO/寄生虫/莲花泛目录解析/泛目录软件)

    莲花泛目录程序强大之处: 1.内容分类详细2.自动推送URL链接3.内置超强原创内容功能系统,页面深受百度搜索引擎喜爱.4.蜘蛛触发繁殖:蜘蛛触发程序任何页面,程序自动生成独立页面并引导繁殖.5.操作 ...

  3. Mybatis源码学习之事务管理(八)

    简述 在实际开发中,数据库事务的控制是一件非常重要的工作,本文将学习Mybatis对事务的管理机制.在Mybatis中基于接口 Transaction 将事务分为两种,一种是JdbcTransacti ...

  4. 20175329&20175313&20175318 2019-2020 《信息安全系统设计基础》实验三

    20175329&20175313&20175318 2019-2020 <信息安全系统设计基础>实验三

  5. Linux设备驱动程序 之 内核符号表

    insmod使用公共内核符号表来解析模块中未定义的符号.功能内核符号表中包含了所有全局内核项(函数和变量)的地址,这是实现模块化驱动程序所必须的.当模块装载到内核后,它所导出的任何符号都会变成内核符号 ...

  6. JVM | 分代垃圾回收策略的基本概念以及过程

    一.为什么要分代 分代的垃圾回收策略,是基于这样一个事实:不同的对象的生命周期是不一样的.因此,不同生命周期的对象可以采取不同的收集方式,以便提高回收效率. 在Java程序运行的过程中,会产生大量的对 ...

  7. jdk与jre与jdk都是干什么的有什么区别和jvm详解:

    1.0,jdk与jre和jvm的区别: JDK(Java Development Kit):指的是Java开发工具集.JDK是整个Java的核心,包括了Java基础类库.Java运行环境(JRE)和J ...

  8. 小D课堂-SpringBoot 2.x微信支付在线教育网站项目实战_6-3.微信网站扫码支付介绍

    笔记 3.微信网站扫码支付介绍     简介:讲解微信网页扫码支付         1.扫码支付文档:https://pay.weixin.qq.com/wiki/doc/api/native.php ...

  9. [CDH] Process data: integrate Spark with Spring Boot

    c 一.Spark 统计计算 简单统计后写入Redis. /** * 订单统计和乘车人数统计 */ object OrderStreamingProcessor { def main(args: Ar ...

  10. [ML] Load and preview large scale data

    Ref: [Feature] Preprocessing tutorial 主要是 “无量纲化” 之前的部分. 加载数据 一.大数据源 http://archive.ics.uci.edu/ml/ht ...