一、保护继承
当派生类中派生出另一个类时,私有继承和保护继承之间的主要区别:
使用私有继承,第三代两类将不能使用基类的接口,是因为基类的公有接口在派生类中将变为私有方法。
使用保护继承时,基类的公有方法在第二代中将变成受保护的,因此第三代可以使用它。
在私有继承或者保护继承时,可以使用using来重新定义访问权限。
二、多重继承
多重继承产生的问题:
(1)从不同的基类继承同名的方法。
(2)从两个或更多相关基类继承同一个类的多个实例。
解决在多重继承的问题是使用虚基类。
1、虚基类
虚基类使得从多个类(基类相同)派生出的对象只继承一个基类对象。
关于虚基类的构造函数的规则:
(1)对于非虚基类,唯一可以出现在初始化列表的构造函数是基类的构造函数。
在c++中,使用虚基类时,静止信息通过中间类自动传递给基类。编译器会默认使用基类的构造函数,也可以显式的调用基类的构造函数。
(2)多重继承导致函数调用的二义性,可以用作用域限定符来解决。
(3)虚基类解决的二义性规则与访问规则无关。(优先级,类b继承类a,b优于a)
三、类模板
容器类设计用来存储其他对象或数据类型。
模板提供参数化类型,即能够将类型名作为参数传递给接收方来建立类或者函数。
由于模板不是函数,它们不能不能单独编译,模板必须与特定的模板实例化放在同一个文件中。
模板多功能性:
1、递归使用模板
vector< vector<int> >array;
2、使用多个类型参数
template<class T1,class T2>
3、默认类型的模板参数(为类型参数提供默认类型)
对于类模板参数可以提供默认值,但对于函数模板不能提供默认值,但可以为非模板参数提供默认值。
关于模板的具体化、显式/隐式实例化
(1)隐式实例化,即它们声明一个或多个对象,指出所属类型,而编译器用通用模板或者具体的类来定义
ArrayTP<int,100>stuff;
(2)显式实例化
使用template并指出所需类型来声明类时,编译器将生成类声明的显示实例化
temple class ArrayTP <string,100>;
(3)显式具体化
是特定的类型(用于替换模板中泛型)的定义(具体类型的模板)
具体模板与通用模板都与实例化请求时,编译器经使用具体化的版本
template<typedef T>
class A
{};
template<>class A<const char *>
{};
(4)部分具体化
关键字template后与< >声明的没有被具体化的参数设置
template <class T>class Pair<T1,int>;
四、成员模板
模板类与友元函数的三种关系:
1、模板类非模板友元函数
template <class T>
class A
{
public:
friend void counts();
};
2、模板类的约束模板友元函数
template <class T>
class A
{
public:
friend void counts<T>();
};
3、模板类非约束友元函数
template <class T>
class A
{
public:
template<typename C,typename D>friend void show(C &a,D &b);
};
五、模板别名
(1)利用typedef重命名
(2)c++新特性:
模板类:
template <typename T>
using arrtype = arrary<T,12>;
arrtype<double>;
非模板:
typedef const char* pc1;
uisng pc2 = const char*;
typedef const int *(*pal)[10];
using pa2 = const int *(*)[10];