第五章第一节 类
protected
protected成员相对于private成员扩大的访问范围表现在:基类的protected成员可以在派生类的成员函数中被访问。
继承
1 | class proQueue : public Queue { /* ... ... */ }; |
类proQueue继承了类Queue;当构造一个派生类对象时,会先调用基类的构造函数;若存在成员是类,会调用成员类的构造函数,最后再调用其自身构造函数,析构函数的调用顺序与之相反。
但是基类的析构函数应设置为虚函数(默认),可以保证当我们new一个子类,然后使用基类指针指向该子类对象,释放基类指针时可以释放掉子类的空间,防止内存泄漏。但是构造函数不能声明为虚函数。
三种继承总结如下图
虚继承
虚继承是解决C++多重继承问题的一种手段,从不同途径继承来的同一基类,会在子类中存在多份拷贝。这将存在两个问题:其一,浪费存储空间;第二,存在二义性问题,通常可以将派生类对象的地址赋值给基类对象,实现的具体方式是,将基类指针指向继承类(继承类有基类的拷贝)中的基类对象的地址,但是多重继承可能存在一个基类的多份拷贝,这就出现了二义性。虚继承可以解决多种继承前面提到的两个问题
1 | class B :virtual public A{}; |
友元
C++中私有变量对外部类是不能直接访问的,也是不能继承的。
使用友元类可以访问类中的私有方法、私有变量,虽然对类的封装有一定的破坏,但是有时也是很实用的。在实际中,在修改已有代码时,为了不大改动已有代码:
对于没有继承关系的类,如果有关联,使用友元类还是比较方便的。
对于有继承关系的类,如果有关联,可以将变量访问由private改为protected。
总结:
外部类可访问public;
友元类可访问public、protected与private;
子类可访问public与protected;
虚函数
使用virtual
关键字修饰的函数为虚函数,子类需要对基类的虚函数进行重写。当基类指针或引用指向派生类对象时,当使用该指针或引用调用基类的虚函数时,会自动调用派生类实现的函数——动态绑定。
- 存在虚函数的类都有一个一维的虚函数表即虚表。每个存在虚函数的类对应一个虚表,该类实例化的每个对象对应一个虚表指针;
- 纯虚函数=虚函数=0;
- 存在至少一个纯虚函数的类即抽象类;抽象类不可实例化,必须由派生类继承重写纯虚函数后。派生类才能被实例化。
构造函数
- 缺省构造函数;
- 拷贝构造函数(参数为const引用);
- 移动构造函数(参数为右值引用);
- 初始化构造函数(程序员定义);
析构函数
销毁类对象之前调用的函数,替类对象返还相关的资源或自动释放资源。与构造函数相对应。
类模板
1 | template <class T> |