继承机制总结
- 在派生类内,派生的成员函数和友元函数可以访问基类的所有公有和保护的数据成员和成员函数
- 在类外,派生类对象只能访问基类的公有数据成员和成员函数,多重继承是一个类从多个基类派生而来 的机制,派生类实际上获取了所有基类的特性。
- 多继承产生二义性时,调用父类成员要使用作用域号;
- 派生类的构造函数必须激活所有基类的构造函数,并把相应的参数传递给它们
- 派生类作为基类继承给其他类时,当派生类的构造函数被激活时,它的所有的基类的构造函数也会被激活,
为解决多继承中的二义性问题,用虚继承,其目的是使公共基类在其派生对象中只产生一个基类子对象。
继承方式的改变 改变的是什么 ```cpp
include
using namespace std; 继承承方式不影响子类访问父类的数据,影响的是父类的 // 成员在子类中拥有什么样的访问属性 class A { private:
int numbera;
protected:
int numberb;
public:
int numberc;
};
class B :private A 私有继承
{
void visit()
{ 在派生类中的属性 派生类的对象访问权限(类外)
cout << numbera; 不可直接访问 不可直接访问
cout << numberb; private 不可直接访问
cout << numberc; private 不可直接访问
}
};
class C :public A 公有继承
{
void visit()
{ 在派生类中的属性 派生类的对象访问权限(类外)
cout << numbera; 不可直接访问 不可直接访问
cout << numberb; protected 不可直接访问
cout << numberc; public #可直接访问
}
};
class D :protected A 保护继承
{
void visit()
{ 在派生类中的属性 派生类的对象访问权限(类外)
cout << numbera; 不可直接访问 不可直接访问
cout << numberb; protected 不可直接访问
cout << numberc; protected 不可直接访问
}
};
// 继承方式限定的是父类的成员在子类中最低的访问权限
// public公有继承 protected保护继承 private私有继承
// private × × ×
// protected protected protected private
// public public protected private
- 不管是什么继承方式,派生类的成员函数和友元函数都可以访问基类中的公有成员和保护成员,但不能访问私有成员
2.在公有继承时,派生类的对象只能访问公有成员,在保护继承和私有继承时,派生类的对象不能访问基类中任何成员。
```
注意:关键字“派生类对象”代表在类外,要留意。
2.继承
单继承:派生类只有一个直接积累的继承方式
多继承;多个基类
接口继承:将类的公有成员函数称为接口,供外部调用。公有继承称为接口继承
实现继承:私有和保护继承下,不继承基类的接口
2.1 基本语法:
<br />class CB: public CA <br /> CB 是CA的子类<br />**子类继承了父类的所有成员,但是无法访问私有成员;可以通过父类的函数间接访问父类的变量;**
2.2 继承的作用
多个类中,在父类的基础上,增加新的功能,提高代码的简洁性,减少冗余。
优点:使代码可以复用,对已有老代码快速扩展,减少冗余。
2.3 继承有三种方式
基类的成员为 private,公有继承(public),私有继承(private),保护继承(protected),都不可直接访问。
1.父类中的私有成员,无论怎么继承,都不能直接访问,私有成员只能在自己的函数中使用
2.公有继承,父类中的公有成员,依然是公有,接口依然是接口,所以公有继承也称为接口继承
- 保护继承和私有继承,都会导致父类的接口消失,这个称之为实现继承
- 保护继承,没有阻断孙子类以及后续的类中,对于爷爷类中函数的访问,无论父类公有还是父类保护,都以保护形式使用
- 私有继承,就阻断了孙子类以及后续的类中,对于爷爷类中函数的访问
2.4 关于 重定义
父类与子类函数或者数据同名,子类继承了父类的数据,但是会屏蔽掉其数据,优先访问自己的。
子类的函数有参数,父类的函数没有参数,重载发生在同一个作用域,才有效。所以在父类和子类无法构成重载
触发时机:
只要父类和子类中函数或变量发生重名,无论参数是否相同,都触发重定义,父类的函数和变量 被屏蔽,子类对象直接调用同名函数,调用子类中的函数。
obj.CBase::Fun1( ) 一定要访问父类的函数或常量时,使用对应类的作用域
2.5构造函数和析构函数的调用(子类不会继承父类的 构造函数和析构函数,会继承其他成员)
注意:正常情况下,如果基类构造是无参构造函数,那么会自动去调用,而不用派生类构造显示调用,如果基类没有无参数构造函数,那么派生了i必须显示调用基类的构造函数
父类和子类都会调用构造函数,优先调用父类的构造函数,再调用自己的构造函数
构造函数 调用优先级:
父类构造>数据成员构造>子类构造
析构函数:调用优先级
子类析构>数据成员析构>父类析构
多个类对象成员的时候,按照初始化列表规则,谁先定义谁先调用。
3.转换构造 只有一个参数的构造函数称为 转换构造函数
4.多继承
一个类,可以有多个父类,继承自多个父类的话,就会拥有所有父类的所有成员。
- 执行顺序:调用多个父类,谁在前面,先调用构造函数。
- 多个成员变量,谁先定义 ,谁先调用
- 多继承中的构造函数的调用顺序:
- 派生类D继承了三个基类,继承方式都是公有继承。类D 的成员包含了类A、类B和类C中的成员,以及它本身的成员
- 如果要创建类D的对象,首先要顺序执行类A、类B、类C的构造函数,再执行派生类D本身的构造函数
class A
{………………};
class B
{………………};
class C
{………………};
class D : public A,public B,public C
{………………};
能被派生类继承的函数——只有成员函数
- 不能继承 构造和析构函数
- 不能继承友元函数(在类内,不属于类)
在C++中,派生类把基类中所有的成员继承过来,除了构造函数和析构函数。 友元函数不属于类,它只是给类开了一个后门 本来类外不可以访问类的私有成员,通过友元函数就可以 所以不能继承。子类继承父类,那么默认的,就是继承了父类的成员函数和成员变量。 初始化子类时,会先自动调用父类的构造函数。然后才调用子类的构造函数 析构时,按相反顺序进行。 构造从类层次的最根处开始,在每一层中,首先调用基类的构造函数,然后调用成员对象的构造函数。析构则严格按照与构造相反的次序执行,该次序是唯一的,否则编译器将无法自动执行析构过程。不能继承,由他们的功能决定。