服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C/C++ - C++继承中的访问控制实例分析

C++继承中的访问控制实例分析

2021-01-28 15:08C++教程网 C/C++

这篇文章主要介绍了C++继承中的访问控制,是面向对象程序设计中非常重要的知识点,需要的朋友可以参考下

本文较为深入的探讨了C++继承中的访问控制,对深入掌握C++面向对象程序设计是非常必要的。具体内容如下:

通常来说,我们认为一个类有两种不同的用户:普通用户 和 类的实现者。其中,普通用户编写的代码使用类的对象,这部分代码只能访问类的公有(接口)成员;实现者则负责编写类的成员和友元的代码,成员和友元既能访问类的公有部分,也能访问类的私有部分。如果进一步考虑继承的话就会出现第三种用户,即派生类。派生类可以访问基类的公有(public)成员和受保护(protected)成员,但不能访问基类的私有(private)成员。

继承相关点如下:

①.大多数类都只继承自一个类,这种形式的继承叫做“单继承”。本文主要讲的是单继承。
②.一个派生类的对象中,包含继承自基类的部分和派生类自定义的部分。正因为派生类含有基类部分,所以可以进行派生类到基类的类型转换,这种转换是隐式的。
③.不存在从基类向派生类的隐式类型转换。
④.派生类向基类的自动类型转换只对指针或引用有效,对象之间不存在类型转换。
⑤.如果基类定义了静态成员,则不论派生出多少个派生类,每个静态成员都只存在唯一实例。
⑥防止一个类被继承可以使用关键字final,这时C++11新标准中提供的。

此外,读者还需要了解一下前面文章所介绍的继承中的虚函数与纯虚函数

一、公有、私有和受保护成员

1 . 访问说明符

在C++中通过使用访问说明符public、protected、private来对类的成员进行访问控制,控制成员对于普通用户或派生类来说是否可访问:

public:定义为public的成员对普通用户、类的实现者、派生类都是可访问的。public通常用于定义类的外部接口。

protected:定义protected成员的目的是让派生类可以访问而禁止其他用户访问。所以类的实现者和派生类可以访问,而普通用户不能访问。

private:定义为private的成员只能被类的实现者(成员和友元)访问。private部分通常用于封装(即隐藏)类的实现细节。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class People{
protected:
  string name;
};
 
class Student : public People{
public:
  friend void Print(Student &s);
  friend void Print(People &p);
};
 
// 正确,可以通过派生类对象访问基类的protected成员
void Print(Student &s){ s.name="Songlee"; cout<< s.name << endl; }
// 错误,不能通过基类对象访问基类的protected成员
void Print(People &p){ p.name="Songlee"; cout<< p.name << endl; }

需要注意的是,派生类的成员或友元只能通过派生类对象来访问基类的受保护成员。派生类对于一个基类对象中的受保护成员没有任何访问特权。

2 . 改变成员的可访问性

有时我们需要改变派生类继承的某个名字的访问级别,通过使用using声明:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class People{
protected:
  string name;
};
 
class Student : public People{
public:
  using People::name; // 将继承来的name成员的访问权限改为public
};
 
int main()
{
  Student me;
  me.name = "SongLee";   // 可以访问name了
  cout << me.name << endl; 
  return 0;
}

通过在类的内部使用using声明语句,我们可以将该类的直接或间接基类中的任何可访问成员(非私有成员)标记出来,改变其访问权限。

二、公有、私有和受保护继承

我们注意到,在类的派生列表中用到了访问说明符public、protected和private,它们分别表示不同的继承方式:

?
1
2
3
class A : public B { /* */ };   // 公有继承
class A : private B { /* */ };  // 私有继承
class A : protected B { /* */ }; // 受保护继承

派生类的派生列表中的访问说明符对于派生类的成员(及友元)能否访问其直接基类的成员没什么影响。派生类的成员(及友元)对基类成员的访问权限只与基类中的访问说明符有关。

那么派生列表中的访问说明符有什么作用呢?

派生列表中访问说明符的作用是控制派生类用户对于基类成员的访问权限,注意是派生类的用户。下面给出不同的继承方式导致的访问权限的变化:

public继承:如果继承是公有的,则成员将遵循其原有的访问说明符。父类中的public、protected和private属性在子类中不发生改变。

protected继承:比protected级别高的访问权限会变成protected。即父类中的public属性在子类中变为protected,父类中的protected和private属性在子类中不变。

private继承:比private级别高的访问权限会变成private。即父类中的三种访问属性在子类中都会变成private。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class A {  // 基类
public:
  string A_public;   // 公有成员
protected:
  string A_protected;  // 受保护成员
};
 
class B : private A {  // 私有继承
public:
  B(){ A_public="public"; A_protected="protected"; };
};
 
int main()
{
  B b;  // 通过B的对象访问
  cout << b.A_public <<" "<< b.A_protected << endl;  // 错误,因为是私有继承
  return 0;
}

如果我们在派生列表中不使用访问说明符,则struct关键字默认的是公有继承,class关键字默认的是私有继承。不过建议在继承时最好显式地将访问说明符写出来。

另外,不同的继承方式也会影响派生类向基类的转换,假定Derive继承自Base:

1.只有当Derive公有地继承自Base时,用户代码才能使用派生类向基类的转换;如果Derive继承Base的方式是受保护的或者私有的,则用户代码不能使用该转换。

2.不论Derive以什么方式继承Base,Derive的成员函数和友元都能使用派生类向基类的转换;派生类向其直接基类的类型转换对于派生类的成员和友元来说永远是可访问的。

3.如果Derive继承Base的方式是公有的或者受保护的,则Derive的派生类的成员和友元可以使用Derive向Base的类型转换;反之,如果Derive继承Base的方式是私有的,则不能使用。

延伸 · 阅读

精彩推荐
  • C/C++OpenCV实现拼接图像的简单方法

    OpenCV实现拼接图像的简单方法

    这篇文章主要为大家详细介绍了OpenCV实现拼接图像的简单方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    iteye_183805102021-07-29
  • C/C++C语言main函数的三种形式实例详解

    C语言main函数的三种形式实例详解

    这篇文章主要介绍了 C语言main函数的三种形式实例详解的相关资料,需要的朋友可以参考下...

    ieearth6912021-05-16
  • C/C++使用C++制作简单的web服务器(续)

    使用C++制作简单的web服务器(续)

    本文承接上文《使用C++制作简单的web服务器》,把web服务器做的功能稍微强大些,主要增加的功能是从文件中读取网页并返回给客户端,而不是把网页代码...

    C++教程网5492021-02-22
  • C/C++c/c++内存分配大小实例讲解

    c/c++内存分配大小实例讲解

    在本篇文章里小编给大家整理了一篇关于c/c++内存分配大小实例讲解内容,有需要的朋友们可以跟着学习参考下。...

    jihite5172022-02-22
  • C/C++深入C++拷贝构造函数的总结详解

    深入C++拷贝构造函数的总结详解

    本篇文章是对C++中拷贝构造函数进行了总结与介绍。需要的朋友参考下...

    C++教程网5182020-11-30
  • C/C++c/c++实现获取域名的IP地址

    c/c++实现获取域名的IP地址

    本文给大家汇总介绍了使用c/c++实现获取域名的IP地址的几种方法以及这些方法的核心函数gethostbyname的详细用法,非常的实用,有需要的小伙伴可以参考下...

    C++教程网10262021-03-16
  • C/C++C语言实现双人五子棋游戏

    C语言实现双人五子棋游戏

    这篇文章主要为大家详细介绍了C语言实现双人五子棋游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    两片空白7312021-11-12
  • C/C++关于C语言中E-R图的详解

    关于C语言中E-R图的详解

    今天小编就为大家分享一篇关于关于C语言中E-R图的详解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看...

    Struggler095962021-07-12