C++ 派生类成员的访问属性
派生类成员的访问属性:
C++继承方式总共分为以下几种:public、private、protected三种(它们直接影响到派生类的成员、及其对象对基类成员访问的规则)。
(1)public(公有继承):继承时保持基类中各成员属性不变,并且基类中private成员被隐藏。派生类的成员只能访问基类中的public/protected成员,而不能访问private成员;派生类的对象只能访问基类中的public成员。
(2)private(私有继承):继承时基类中各成员属性均变为private,并且基类中private成员被隐藏。派生类的成员也只能访问基类中的public/protected成员,而不能访问private成员;派生类的对象不能访问基类中的任何的成员。
(3)protected(保护性继承):继承时基类中各成员属性均变为protected,并且基类中private成员被隐藏。派生类的成员只能访问基类中的public/protected成员,而不能访问private成员;派生类的对象不能访问基类中的任何的成员。

由上表可知:
public继承:不改变基类成员的访问控制。
private继承:派生类所继承的基类成员的访问控制都变为private。
protected继承:基类中的private成员的访问控制不变,其余的都变为protected。
基类的 public成员被派生类继承,且在派生类中是可见的(visible in the derived class)。
基类的 private成员被派生类继承,但在派生类中是不可见的(not visible in the derived class)。
受保护成员 protected Members
以下面两个例子来说明受保护成员的可见性。
class BC
{
public:
void set_x( int a )
{
x = a;
}
protected:
int get_x( ) const
{
return x;
}
private:
int x;
};
class DC : public BC
{
public:
void add2()
{
int c=get_x();//可以执行
set_x(c+2);//可以执行
}
}
void g()
{
DC d;
d.get_x( );//在客户代码中不可见,不能够执行
}
class BC
{
protected:
int get_w( ) const;
//……
};
class DC : public BC
{
public:
int get_val( ) const
{
return get_w( );//派生类中可见,可以执行
}
void base_w( const BC& b ) const
{
cout << b.get_w( ) << endl;//客户代码中不可见,不能够执行
}
};
保护成员是专为继承机制而设的。
受保护成员(A protected member)仅在自己的类和其派生类中是可见的。
继承方式不会影响基类成员在派生类中的能见度。
名字隐藏 Name hiding
如果在派生类中添加了成员(数据、函数),其与基类的成员重名,本地成员(the local member)隐藏继承来的成员 ( hides the inherited member)。
以下面的代码为例:
class BC {
public:
void h( float );
};
class DC : public BC {
public:
void h( char[ ] );
};
DC继承自BC,其中BC含有void h(float)函数,DC中含有void h(char[])函数,这两个函数的签名不同,那么是否能够构成函数的重载呢?
对于下面的两行代码都能够执行?
void f ( )
{
DC d1;
d1.h( "Boffo!" );//可以执行
d1.h( 707.7 );//不可以执行
}
其实这种想法是不对的,重载必须是同一级的函数才能构成,而这两个函数的级别是不一致的,本地成员void h(char[])将会隐藏继承来的成员 void h(float)!!
void f ( )
{
DC d1;
d1.BC::h( 707.7 );//这样写是可以的
}
再就一个例子
对于一个实现数组升序的类继承自一个数组类。
class Array
{
public:
void insert(int X)
{
将X插入到 last_pos 指定的位置;
last_pos++;
}
private:
int last_pos;
//……
};
class AscArray : public Array
{
public:
void insert( int X )
{
确定插入的位置,并将X插入
// ...
}
// ...
};
其调用函数如下调用语法是正确的,但是其内涵错误
void f (AscArray& as )
{
as.insert( );//正确,排序数组类中插入10然后实现排序
as.Array::insert();//不正确,使用了数组类的插入方法,将10插入到了数组尾部,并不能实现排序功能 }
调整可访问性 Adjusting access
一个继承成员的访问控制可能通过使用using声明( using declaration)改变。
还是上面那个例子。
class AscArray : public Array
{
private:
using Array::insert;
//将基类的public成员的外部访问权降低,使得无法通过派生类对象访问该成员!
public:
void insert( int X ) {
确定插入的位置,并将X插入
// ...
}
// ...
};
void f(AscArray& as )
{
as.insert( );//正确
as.Array::insert();//运行错误
}
在使用using声明时,基类中公有的成员在公共派生类中必须是公有的,只有这样才能保证公有继承时“派生类对象是一个基类对象”的逻辑关系。
在基类中的private成员,不能在派生类中任何地方用using声明。
同时,在基类中的protected成员,可在public派生下通过using声明改为public成员。
#include <iostream>
using namespace std;
class A
{
protected:
void PrintA( )
{
cout << "A::Print"<<endl ;
}
};
class B: public A
{
public:
using A::PrintA;//改为公有
public:
void PrintB( )
{
cout << "B::Print" <<endl;
}
};
int main( )
{
A a;
B b;
b.PrintB( );
b.PrintA( );
return ;
}

C++ 派生类成员的访问属性的更多相关文章
- C++:调整基类成员在派生类中的访问属性的其他方法(同名成员和访问声明)
4.3 调整基类成员在派生类中的访问属性的其他方法 4.3.1 同名函数 在定义派生类的时候,C++语言允许在派生类中说明的成员与基类中的成员名字相同,也就是 说,派生类可以重新说明与基类成员同名的成 ...
- C++学习之路—继承与派生(一):基本概念与基类成员的访问属性
(本文根据<c++程序设计>(谭浩强)总结而成,整理者:华科小涛@http://www.cnblogs.com/hust-ghtao,转载请注明) 1 基本思想与概念 在传统的程序设计 ...
- 3.3 C++改变基类成员在派生类中的访问属性
参考:http://www.weixueyuan.net/view/6360.html 总结: 使用using声明可以改变基类成员在派生类中的访问属性. private: using book::se ...
- 不可或缺 Windows Native (21) - C++: 继承, 组合, 派生类的构造函数和析构函数, 基类与派生类的转换, 子对象的实例化, 基类成员的隐藏(派生类成员覆盖基类成员)
[源码下载] 不可或缺 Windows Native (21) - C++: 继承, 组合, 派生类的构造函数和析构函数, 基类与派生类的转换, 子对象的实例化, 基类成员的隐藏(派生类成员覆盖基类成 ...
- python-面向对象(四)——类成员的访问方式汇总
类成员的访问方式 #!/usr/bin/env python # _*_coding:utf-8 _*_ class pepole(object): '''This is __doc__ inform ...
- CPP/类/成员函数访问权限2
// main.cpp // OOL // Created by mac on 2019/4/4. // Copyright © 2019年 mac. All rights reserved. // ...
- C++继承具体解释之二——派生类成员函数具体解释(函数隐藏、构造函数与兼容覆盖规则)
在这一篇文章開始之前.我先解决一个问题. 在上一篇C++继承详解之中的一个--初探继承中,我提到了在派生类中能够定义一个与基类成员函数同名的函数,这样派生类中的函数就会覆盖掉基类的成员函数. 在谭浩强 ...
- C++——派生类中的访问——可见性问题
C++中派生类对基类成员的访问形式主要有以下两种: 1.内部访问:由派生类中新增成员对基类继承来的成员的访问. 2.对象访问:在派生类外部,通过派生类的对象对从基类继承来的成员的访问.今天给大家介绍在 ...
- 在client类中设置访问属性 address,business和individua
php 5.4中的traits,是新引入的特性,中文还真不知道如何准确翻译好.其实际的目的, 是为了有的场合想用多继承,但PHP又没多继承 ,于是就发明了这样的一个东西. Traits可以理解为一组能 ...
随机推荐
- 菜鸟对APP界面设计的一些心得小结
1. 前言 当我看着我以前做的一些app界面,我意识到我应该把我的界面设计能力水平再提升一个,因为实在是丑啊!贴一些以前的设计: 现在看来,是不能看的了.我主要是做需求设计,后面也有一些美工的工作,我 ...
- 团队作业——Alpha冲刺 1/12
团队作业--Alpha冲刺 Alpha 阶段认领的任务 杨光海天:加入随心摘首页和编辑界面的开发中,并完成冲刺博文的撰写 郭剑南.周琪文:图像识别核心算法的实现 赖志平:随心摘首页和编辑界面开发主力, ...
- [BUG]自己的bug自己解,记一次在变量使用过程引发的bug
[实现的功能要求]在短信编辑界面,将所有的emoji表情全部插入到编辑区域,其中表情共有5页,每遍历完一页时需要自动翻页重新获取表情并插入,在第5页中只有10个表情 下面先看看这段代码,大家能否看出有 ...
- Learn Algorithms With Javascript - 基于 Js 进行算法学习
基于 javascript 学习并实现常用的经典算法,欢迎对算法和数学感兴趣的 Js 开发者参与,一起学习共同进步. 算法实现 排序 插入排序 sort/lib/insertion-sort.js 希 ...
- Vuex状态管理详解
什么是Vuex 专门为vue应用程序开发的状态管理模式,采用集中式存储管理应用的所有组件的状态(数据),以相应的规则保证状态以一种可预测的方式发生改变 Vuex的作用(什么样的情况下使用Vuex) 多 ...
- bat替换文件的指定内容
需求:替换文件my.ini中的1000 为10000,bat脚本如下: c:cd C:\Program Files\MySQL\MySQL Server 5.5copy my.ini my1126ba ...
- 记一次Eclipse关于JDK和JRE的问题
今天同事遇到个问题,发现import package居然报错,但是那个package实际上存在.一般情况某个类有问题或者是该类中的方法有问题,总会在IDE中显示一条红线.但是这次确实是没有问题.我找到 ...
- 用scp命令来通过ssh传输文件,ssh推送.py程序到CentOS7服务器端出现lost connection错误
ssh推送.py程序到CentOS7服务器端运行出现lost connection错误 (base) F:\workspace>dir 驱动器 F 中的卷是 新加卷 卷的序列号是 C2B9-62 ...
- DD-WRT
定时任务: 每日凌晨1點關, 星期1-, 上午7點半開, 8點半關, 晚上9點開 星期6/日, 上午開10點開 administration -> management -> enable ...
- Centos7-安装Gradle4.10
1.下载 官方安装文档:https://gradle.org/install/ 官方下载地址:http://services.gradle.org/distributions/gradle-4.10- ...