“has-a”关系
通常有两种方法实现:
1、被包含,本身是另一个类的对象。
2、私有或者保护继承。
主要讨论第二种方法,在继承时使用private关键字(或者不用任何关键字,默认就是私有的)。
使用私有继承,则基类的所有成员在派生类中都将成为私有的成员。此时,派生类将继承基类的实现,而不继承接口。
多重继承(MI)
每个基类都需要使用关键字,否则是默认private继承。
使用MI带来的问题:1、从两个不同基类继承了同名方法。
2、从多个基类继承了同一个类的多个实例。
解决方法:1、使用类限定符来区别不同基类中的同名方法;
2、在继承时使用virtual关键字,基类就成为虚基类,这样从虚基类派生出来的类将只继承一个基类对象;
3、使用虚基类时,通过优先规则解决名称二义性。
优先规则:派生类中的名称优先于直接或者间接父类中的相同名称。
类模板定义
在类声明前使用:
template <class T>
模板成员函数也需要在实现前添加模板声明:
template<class T> void ClassName<T>::Function() { // }
特例:如果成员函数是类声明中定义的,则可以省略模板前缀。
另外,可以使用显式具体化覆盖模板定义的类声明:
template <> class ClassName<char*> { //..... }
这样在使用class ClassName<char*> classForChar;时将会使用显式具体化的类定义,而不会使用通用定义。
类模板可以指定多个类型参数,也可以有非类型参数,甚至可以包含本身是模板的参数。
类模板使用
类模板和成员函数模板只是C++编译器指令,而不是类和成员函数的定义,所以类定义在声明类对象并指定类型时生成。
模板必须和实例化一起使用,有两种解决方法:
1、将模板和实例化放在同一个文件中;
2、使用export关键字,在每个模板声明前都加上export,这样就可以和使用一般类一样使用模板类。
模板类也可以用作其它类或模板的成员。