一、基类

    从一个类派生出另一个类时,原始类称为基类,继承类称为派生类。

派生类对自身基类的private成员没有访问权限,对基类对象的protected成员没有访问权限,对派生类对象的(基类之外)的private和protected成员具有访问权限。

由于C++基础不好,平时也不用它,导致今天才纠正一个非常关键的错误,类的访问权限,是对类而言的,而不是对类的对象而言的。一直都理解错了。这句话都没脸写出来,还是写下来了。

下面是一段简答的测试代码。对于调用成员函数的对象test,基类形参,派生类形参三者的访问权限做了测试如下:

    #include <iostream>
using namespace std; class base
{
public:
int pub;
protected:
int pro;
private:
int pri;
}; class derive : public base
{
public:
int newpub;
protected:
int newpro;
private:
int newpri; public:
int func(class base a, class derive b)
{
//////////////////////////////////////////
自身的 基类成员和非基类成员访问权限测试
cout << newpub << endl;
cout << newpro << endl;
cout << newpri << endl;
cout << pub << endl;
cout << pro << endl;
// no access cout << pri << endl; /////////////////////////////////////////
对基类对象访问权限的测试
cout << a.pub << endl;
// no access cout << a.pro << endl;
// no access cout << a.pri << endl; /////////////////////////////////////////
对派生类对象的基类以及非基类成员访问权限测试
cout << b.pub << endl;
cout << b.pro << endl;
//no access cout << b.pri << endl;
cout << b.newpub << endl;
cout << b.newpro << endl;
cout << b.newpri << endl;
//////////////////////////////////////// return 0;
}
}; int main()
{
class base a;
class derive b;
class derive test;
test.func(a, b);
return 0;
}

 

对基类进行继承时,三种继承方式下,基类的三种访问权限在子类中会有如何的变化这个问题,本科时上C++这门课的时候曾仔细的分析并弄得挺清楚,后来时间久了、用的也不多,慢慢的又变得心里不太有谱了。这次接着准备面试的契机,又重新仔细分析了一番,留个案底,以免再犯糊涂。

三种访问权限

public:可以被任意实体访问
    protected:只允许子类及本类的成员函数访问
    private:只允许本类的成员函数访问

三种继承方式

public 继承  
    protect 继承
    private 继承

组合结果

基类中      继承方式             子类中

public     & public继承        => public
    public     & protected继承     => protected  
    public     & private继承      
=> private

protected  & public继承        => protected
    protected  & protected继承     => protected  
    protected  & private继承       => private

private    & public继承        => 子类无权访问
    private    & protected继承     => 子类无权访问
    private    & private继承       => 子类无权访问

由以上组合结果可以看出

1、public继承不改变基类成员的访问权限
    2、private继承使得基类所有成员在子类中的访问权限变为private
    3、protected继承将基类中public成员变为子类的protected成员,其它成员的访问       权限不变。
    4、基类中的private成员不受继承方式的影响,子类永远无权访问。

此外,在使用private继承时,还存在另外一种机制:准许访问。

我们已经知道,在基类以private方式被继承时,其public和protected成员在子类中变为private成员。然而某些情况下,需要在子类中将一个或多个继承的成员恢复其在基类中的访问权限。

C++支持以两种方式实现该目的

方法一,使用using 语句,这是C++标准建议使用的方式
    方法二,使用访问声明,形式为 base-class::member;,位置在子类中适当的访问声明处。(注,只能恢复原有访问权限,而不能提高或降低访问权限)

以下是简单的试验代码 

#include <iostream>

using namespace std;

class Grand
{
public:
void public_foo (){}
protected:
void protected_foo(){}
private:
void private_foo(){}
}; class Father:public Grand
{
public:
void f_public_test() {public_foo(); }
void f_protected_test() {protected_foo(); }
// void f_private_test() {private_foo(); }
}; class Child:public Father
{
public:
void c_protected_test() {protected_foo(); }
// void c_private_test() {private_foo();}
}; int main( int argc, char* argv[])
{
Father objF; // objF.protected_foo(); return 1; } //protected.cpp #include <iostream> using namespace std; class Grand
{
public:
void public_foo (){}
protected:
void protected_foo(){}
private:
void private_foo(){}
}; class Father:protected Grand
{
public:
void f_public_test() {public_foo(); }
void f_protected_test() {protected_foo(); }
// void f_private_test() {private_foo(); }
}; class Child:public Father
{
public:
void c_protected_test() {protected_foo(); }
// void c_private_test() {private_foo();}
}; int main( int argc, char* argv[])
{
Father objF; // objF.public_foo();
// objF.protected_foo(); return 1; } //private.cpp #include <iostream> using namespace std; class Grand
{
public:
void public_foo (){}
protected:
void protected_foo(){}
private:
void private_foo(){}
}; class Father:private Grand
{
public:
void f_public_test() {public_foo(); }
void f_protected_test() {protected_foo(); }
// void f_private_test() {private_foo(); }
}; class Child:public Father
{
public:
// void c_protected_test() {protected_foo(); }
// void c_private_test() {private_foo();}
}; int main( int argc, char* argv[])
{
Father objF; // objF.public_foo();
// objF.protected_foo(); return 1; }

C++ primer(十三)--类继承、构造函数成员初始化、虚函数、抽象基类的更多相关文章

  1. OOP2(虚函数/抽象基类/访问控制与继承)

    通常情况下,如果我们不适用某个函数,则无需为该函数提供定义.但我们必须为每个虚函数都提供定义而不管它是否被用到了,这因为连编译器也无法确定到底会适用哪个虚函数 对虚函数的调用可能在运行时才被解析: 当 ...

  2. 构造函数为什么不能为虚函数 &amp; 基类的析构函数为什么要为虚函数

    一.构造函数为什么不能为虚函数 1. 从存储空间角度,虚函数相应一个指向vtable虚函数表的指针,这大家都知道,但是这个指向vtable的指针事实上是存储在对象的内存空间的.问题出来了,假设构造函数 ...

  3. C++ 虚函数在基类与派生类对象间的表现及其分析

    近来看了侯捷的<深入浅出MFC>,读到C++重要性质中的虚函数与多态那部分内容时,顿时有了疑惑.因为书中说了这么一句:使用“基类之指针”指向“派生类之对象”,由该指针只能调用基类所定义的函 ...

  4. PythonI/O进阶学习笔记_3.2面向对象编程_python的继承(多继承/super/MRO/抽象基类/mixin模式)

    前言: 本篇相关内容分为3篇多态.继承.封装,这篇为第二篇 继承. 本篇内容围绕 python基础教程这段: 在面向对象编程中,术语对象大致意味着一系列数据(属性)以及一套访问和操作这些数据的方法.使 ...

  5. c++之——抽象基类

    在一个虚函数的声明语句的分号前加上 =0:就可以将一个虚函数变成纯虚函数,其中,=0只能出现在类内部的虚函数声明语句处.纯虚函数只用声明,而不用定义,其存在就是为了提供接口,含有纯虚函数的类是抽象基类 ...

  6. C++基类的析构函数定义为虚函数的原因

    1:每个析构函数只会清理自己的成员(成员函数前没有virtual).2:可能是基类的指针指向派生类的对象,当析构一个指向派生类的成员的基类指针,这时程序不知道这么办,可能会造成内存的泄露,因此此时基类 ...

  7. python(七):元类与抽象基类

    一.实例创建 在创建实例时,调用__new__方法和__init__方法,这两个方法在没有定义时,是自动调用了object来实现的.python3默认创建的类是继承了object. class A(o ...

  8. thrift之TTransport类体系原理及源码详细解析1-类结构和抽象基类

    本章主要介绍Thrift的传输层功能的实现,传输的方式多种多样,可以采用压缩.分帧等,而这些功能的实现都是相互独立,和上一章介绍的协议类实现方式比较雷同,还是先看看这部分的类关系图,如下: 由上面的类 ...

  9. Python 接口:从协议到抽象基类

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 15.0px Helvetica } 抽象基类的常见用途:实现接口时作为超类使用.然后,说明抽象基类如何检查 ...

  10. 【Python】【元编程】【从协议到抽象基类】

    """class Vector2d: typecode = 'd' def __init__(self,x,y): self.__x = float(x) self.__ ...

随机推荐

  1. SQL Server 禁止和启用约束

    Alter Table XXX nocheck constraint xxx Alter Table XXX check constraint xxx

  2. BusyBox编译配置

    1.  下载Busybox tar包,如busybox-1.23.0.tar.bz2. 官网:http://www.busybox.net/ 2.   make distclean:清除原有配置 ma ...

  3. Oracle数据误删除的恢复操作

    flashbackup 闪回操作: 1. 打开表的闪回功能: alter table dw_stg.fm_user_play_d enable row movement; 2. 查询要闪回的表的记录信 ...

  4. linux下使用yum安装telnet

    参考文章: http://futeng.iteye.com/blog/2039490?utm_source=tuicool&utm_medium=referral

  5. JVM监控工具用法指导

    JVM监控工具用法指导 2010-09-27 15:39 dolphin-ygj javaeye.com 字号:T | T 通过JVM监控工具的使用可以及时发现问题,剔除安全隐患,这里向大家描述一下常 ...

  6. div 画园

    .destination1{ border: #666 solid 1px; box-shadow:-1px 1px 5px 0px #333; width:922px; height:485px; ...

  7. QThread 的使用方法及函数解析

    近日,使用QThread,一些问题百思不得其解,看过大牛的文章,恍然大悟啊. 原文 http://hi.baidu.com/dbzhang800/item/c14c97dd15318d17e1f46f ...

  8. 关于Cocos Studio制作游戏资源

    没想到,Cocos Studio居然是做游戏资源的,而且可以做骨骼动画,虽然我还不会做,只能自己一个人慢慢研究了.学长以前说,Coocs Studio只是用来打包项目成Apk的,没有什么卵用,刚开始我 ...

  9. C++ Primer学习笔记(三) C++中函数是一种类型!!!

    C++中函数是一种类型!C++中函数是一种类型!C++中函数是一种类型! 函数名就是变量!函数名就是变量!函数名就是变量! (---20160618最新消息,函数名不是变量名...囧) (---201 ...

  10. VS2008兼容安装

    1. 直接安装出现问题:该项目的所有配置都需要系统提供对某些 平台的支持,但在此计算机上没有安装这些平台.因此无法加载该项目. 解决方法:先卸载原来安装的, 再设置安装包中的setup.exe的兼容性 ...