面试的时候经常会有很多概念性的东西,许久不用都会很生疏,特意整理一下方便自己以后不记得了可以查看一下,也顺便帮助自己复习一下。
- 概念
继承是面向对象程序设计的一个重要特性,它允许在既有类的基础上创建新的类,新类可以从一个或者是多个既有类中继承函数和数据,还可以重新定义或加入新的数据和函数。
- 基类成员在派生类中的访问属性归纳
我们了解类的成员可以有public、protected、private三种访问属性,类的自身成员可以访问类中的任何成员,但是通过对象访问的话,就只能访问类的public(公有)成员。
类的继承方式有public(公有继承)、protected(保护继承)、private(私有继承)。
在派生类中,基类成员的访问属性可以归纳为四种:不可直接访问,public,protected,private。
在基类中的访问属性 |
继承方式 |
在派生类中的访问属性 |
private |
public |
不可直接访问 |
private |
private |
不可直接访问 |
private |
protected |
不可直接访问 |
protected |
public |
protected |
protected |
private |
private |
protected |
protected |
protected |
public |
public |
public |
public |
private |
private |
public |
protected |
protected |
归纳一下就是:
(1). 基类的私有成员
无论是那种继承方式,基类的私有成员都不允许派生类继承。也就是派生类中不可直接访问的。
(2). 基类的保护成员
公有继承时,基类中得所有公有成员在派生类中以保护成员的身份出现。
保护继承时,基类中得所有保护成员在派生类中以保护成员的身份出现。
私有继承时,基类中得所有私有成员在派生类中以私有成员的身份出现。
(3). 基类的公有成员
公有继承时,基类中得所有公有成员在派生类中以公有成员的身份出现。
保护继承时,基类中得所有保护成员在派生类中以保护成员的身份出现。
私有继承时,基类中得所有私有成员在派生类中以私有成员的身份出现。
- 派生类对基类成员的访问规则
我们都知道,派生类对基类的访问形式主要有以下两种方式:(1).内部访问,有派生类新增的成员对基类继承过来的成员进行访问。(2).对象访问,在派生类的外部,通过定义派生类的对象来对基类继承来得成员进行访问。
那我们来分析三种继承方式下面,派生类对基类的访问规则。
i. 私有继承的访问规则
基类成员 |
Private成员 |
Public成员 |
Protected成员 |
内部访问 |
不可访问 |
可以访问 |
可以访问 |
对象访问 |
不可访问 |
不可访问 |
不可访问 |
首先,我们根据一个具体的例子来看一下。
1 //基类 2 class Base 3 { 4 public: 5 Base(int a, int b, int c): x(a),y(b),z(c) 6 {} 7 virtual ~Base(void); 8 9 int x; 10 void printX() 11 { 12 printZ(); // 间接的访问基类的private成员 13 printf("X = %d\n", x); 14 } 15 16 protected: 17 int y; 18 void printY() 19 { 20 printf("Y = %d\n", y); 21 } 22 23 private: 24 int z; 25 void printZ() 26 { 27 printf("Z = %d\n", z); 28 } 29 }; 30 31 //派生类 32 #include "base.h" 33 34 class Derivel : 35 private Base 36 { 37 public: 38 Derivel(int a, int b, int c):Base(a,b,c) 39 {} 40 virtual ~Derivel(void); 41 42 void show() 43 { 44 printX(); // 正确,基类的公有成员,派生类内部访问可能 45 printY(); // 正确,基类的保护成员,派生类内部访问可能 46 printZ(); // 错误,基类的私有成员,派生类不能内部访问 47 } 48 }; 49 50 // main 51 #include "Base.h" 52 #include "Derivel.h" 53 54 int _tmain(int argc, _TCHAR* argv[]) 55 { 56 Derivel a(1,2,3); 57 58 a.printX(); 59 // 错误,基类的公有成员,私有继承后作为派生类的私有成员,不能外部访问 60 a.printY(); 61 // 错误,基类的保护成员,私有继承后作为派生类的私有成员,不能外部访问 62 a.printZ(); 63 // 错误,基类的私有成员,私有继承后作为派生类的私有成员,不能外部访问 64 a.show(); 65 return 0; 66 }
总结:
当类的继承方式为私有继承的时候,基类的public和protected成员被继承后作为派生类的私有成员。在类的外部通过派生类的对象无法访问,但在派生类的内部是可以直接访问的。基类的private成员在派生类的内部是不能直接访问的,在派生类的外部同样也是不能访问的。如果你想访问的话,可以通过基类提供的public成员函数间接访问。
ii. 公有继承的访问规则
基类成员 |
Private成员 |
Public成员 |
Protected成员 |
内部访问 |
不可访问 |
可以访问 |
可以访问 |
对象访问 |
不可访问 |
可以访问 |
不可访问 |
首先,我们根据一个具体的例子来看一下。
1 //基类 2 class Base 3 { 4 public: 5 Base(int a, int b, int c): x(a),y(b),z(c) 6 {} 7 virtual ~Base(void); 8 9 int x; 10 void printX() 11 { 12 printZ(); // 间接的访问基类的private成员 13 printf("X = %d\n", x); 14 } 15 16 protected: 17 int y; 18 void printY() 19 { 20 printf("Y = %d\n", y); 21 } 22 23 private: 24 int z; 25 void printZ() 26 { 27 printf("Z = %d\n", z); 28 } 29 }; 30 31 //派生类 32 #include "base.h" 33 34 class Derivel : 35 public Base 36 { 37 public: 38 Derivel(int a, int b, int c):Base(a,b,c) 39 {} 40 virtual ~Derivel(void); 41 42 void show() 43 { 44 printX(); // 正确,基类的公有成员,派生类内部访问可能 45 printY(); // 正确,基类的保护成员,派生类内部访问可能 46 printZ(); // 错误,基类的私有成员,派生类不能内部访问 47 } 48 }; 49 50 // main 51 #include "Base.h" 52 #include "Derivel.h" 53 54 int _tmain(int argc, _TCHAR* argv[]) 55 { 56 Derivel a(1,2,3); 57 a.printX(); 58 // 正确,基类的公有成员,公有继承后作为派生类的公有成员,可以外部访问 59 a.printY(); 60 // 错误,基类的保护成员,公有继承后作为派生类的保护成员,不能外部访问 61 a.printZ(); 62 // 错误,基类的私有成员,公有继承后作为派生类的私有成员,不能外部访问 63 a.show(); 64 return 0; 65 }
总结:
当类的继承方式为公有继承的时候,基类的public成员被继承后作为派生类的公有成员。在类的外部通过派生类的对象和派生类的内部都可以直接访问。基类的protected成员被继承后作为派生类的保护成员,在类的外部通过派生类的对象不能访问,只能在派生类的内部访问。基类的private成员被继承后作为派生类的私有成员,在派生类的内部是不能直接访问的,在派生类的外部同样也是不能访问的。
iii. 保护继承的访问规则
基类成员 |
Private成员 |
Public成员 |
Protected成员 |
内部访问 |
不可访问 |
可以访问 |
可以访问 |
对象访问 |
不可访问 |
不可访问 |
不可访问 |
首先,我们根据一个具体的例子来看一下。
1 // 基类 2 class Base 3 { 4 public: 5 Base(int a, int b, int c): x(a),y(b),z(c) 6 {} 7 virtual ~Base(void); 8 9 int x; 10 void printX() 11 { 12 printZ(); // 间接的访问基类的private成员 13 printf("X = %d\n", x); 14 } 15 16 protected: 17 int y; 18 void printY() 19 { 20 printf("Y = %d\n", y); 21 } 22 23 private: 24 int z; 25 void printZ() 26 { 27 printf("Z = %d\n", z); 28 } 29 }; 30 31 // 派生类 32 #include "base.h" 33 34 class Derivel : 35 protected Base 36 { 37 public: 38 Derivel(int a, int b, int c):Base(a,b,c) 39 {} 40 virtual ~Derivel(void); 41 42 void show() 43 { 44 printX(); // 正确,基类的公有成员,派生类内部访问可能 45 printY(); // 正确,基类的保护成员,派生类内部访问可能 46 printZ(); // 错误,基类的私有成员,派生类不能内部访问 47 } 48 }; 49 50 // main 51 #include "Base.h" 52 #include "Derivel.h" 53 54 int _tmain(int argc, _TCHAR* argv[]) 55 { 56 Derivel a(1,2,3); 57 a.printX(); 58 // 错误,基类的公有成员,保护继承后作为派生类的保护成员,不能外部访问 59 a.printY(); 60 // 错误,基类的保护成员,保护继承后作为派生类的保护成员,不能外部访问 61 a.printZ(); 62 // 错误,基类的私有成员,保护继承后作为派生类的私有成员,不能外部访问 63 a.show(); 64 return 0; 65 }
总结:
当类的继承方式为保护继承的时候,基类的public成员被继承后作为派生类的保护成员。在类的外部通过派生类的对象不能访问,在派生类的内部可以直接访问。基类的protected成员被继承后作为派生类的保护成员,在类的外部通过派生类的对象不能访问,只能在派生类的内部访问。基类的private成员被继承后作为派生类的私有成员,在派生类的内部是不能直接访问的,在派生类的外部同样也是不能访问的。