一、继承
1. 继承的概念
继承是面向对象的三大特征之一,体现了代码复用的的思想。继承就是在一个已经存在的类的基础上建立一个新的类,并且拥有其特性。已存在的类被称为基类(父类),新建的类被成为派生类(子类)。
#include <iostream>
using namespace std
class Father
{
private:
string name;
int age;
public:
void show_info()
{
cout << name << " " << name << endl;
}
};
class Son:public Father
{
};
上面的代码中,Son类的功能几乎与Father类重叠,但是在实际使用过程中,派生类可以修改基类中的内容,其中基类的公有属性可以直接更改,而私有属性需要用基类中提供的公有接口来修改。
在派生类中添加一个与基类同名同参数的函数,可以隐藏基类中的函数,如果想要调用基类中的接口,可以通过类名::函数来实现。
2. 构造函数
基类中的构造函数和析构函数不能被继承
2.1 补充基类的无参构造函数
2.2 手动在派生类中调用基类的构造函数
2.2.1 透传构造
透传构造就是在一个类中通过调用另一个类中的构造函数来初始化对象,可以通过构建初始化列表等方式实现。
2.2.2 委托构造
委托构造允许一个构造函数委托给同一个类中的另一个构造函数来完成初始化工作,委托构造的性能要低于透传构造,但是它的代码维护性要好一些,因为一个类中的构造函数都会委托给能力最强,参数最多的构造函数来实现,代码重构的时候只需要修改最强的那个构造函数就可以。
2.2.3 继承构造
继承构造也是C++11中新引入的方法,在派生类中添加一句using Father::Father,就可以将基类中的所有构造函数添加到派生类中,每个派生类中的构造函数都通过透传构造调用对应格式的基类构造函数。
3. 对象的创建与销毁流程
#include <iostream>
using namespace std;
class Value
{
private:
string str;
public:
Value(string str):str(str)
{
cout << str << "构造函数" << endl;
}
~Value()
{
cout << str << "析构函数" <<endl;
}
};
class Father
{
public:
static Value s_value;
Value val = Value("Father成员变量");
Father()
{
cout << "Father 构造函数被调用" << endl;
}
~Father()
{
cout << "Father 析构函数被调用" << endl;
}
};
Value Father::s_value = Value("静态FatherValue被创建");
class Son:public Father
{
public:
static Value s_value;
Value val = Value("son成员变量");
Son()
{
cout << "Son 构造函数被调用" << endl;
}
~Son()
{
cout << "Son 析构函数被调用" << endl;
}
};
Value Son::s_value = Value("静态SonValue被创建了");
int main()
{
cout << "主函数被调用" << endl;
{
Son s;
cout << "对象执行中" << endl;
}
cout << "主函数结束" << endl;
return 0;
}
根据上面的结果,可以得到一些规律
1.静态的创建在程序开始的时候就已经创建完毕。
2.在创建的过程中,基类先被创建出来,派生类后创建;销毁时,派生类先被销毁,基类后销毁。
4.多重继承
4.1 概念
多重继承即一个派生类可以有多个基类,派生类对每个基类的关系仍可以看作一个单继承。
这里注意区分多重继承与多层继承,多层继承是指一层一层继承
4.2 可能出现的问题
4.2.1 重名问题
4.2.2 菱形继承
解决方法:
1. 通过类名调用
2. 使用虚继承,virtual关键字实现
使用虚继承的时候,类中会产生一张虚基类表,这个表不占用存储空间,程序启动时加载到内存中。
当虚继承的时候,D类对象会同时拥有两个虚基类表指针成员,调用的时候查表解决二义性问题
二、权限
1. 权限修饰符
一共三种权限修饰符:private(私有)、protected(保护)、public(公有)
类内 | 派生类中 | 全局 | |
private | √ | × | × |
protected | √ | √ | × |
public | √ | √ | √ |
2. 不同权限的继承
2.1 公有继承
2.2 保护继承
2.3 私有继承
在私有继承中,派生类可以继承基类的成员,但是不能直接访问基类的私有成员。基类的公有成员与保护成员在派生类中都是私有权限。