第13章
派生类不能直接访问基类的私有成员,而必须通过基类方法来访问。派生类的构造函数会先创建基类,如果不调用基类的构造函数,将使用默认的基类构造函数。复制构造函数同理。
释放内存顺序相反。基类指针可以指向派生类对象,基类引用可以在不进行显式类型转换的情况下引用派生类对象。反之不可。
可以用派生类初始化基类,将自动调用隐式复制构造函数。也可以用基类初始化派生类。虚函数会根据引用或指针指向来选择方法。经常在基类中把派生类会重写的方法声明为虚方法,在基类中声明为虚方法后,在派生类中自动成为虚方法,但是一般为了区别两个类中都会加上virtual。
派生类中调用公有的基类方法必须使用作用域解析符。
基类中一般都定义了虚析构函数,因为如果析构函数不是虚的,则只会调用指针类型的析构函数。
静态联编:在编译阶段确定函数应该调用哪一个;动态联编:在运行阶段再决定调用哪一个函数。例如虚函数。
向上强制转换:派生类引用或者指针转换为基类引用或指针;
向下强制转换:基类引用或者指针转换为派生类引用或指针;虚函数工作原理:
给每个对象添加一个隐藏成员,该成员保存了一个指向函数地址数组的指针,这种数组就是虚函数表,虚函数表中有类对象进行声明的虚函数的地址。调用虚函数的时候,程序就在表中查找对象的虚函数表地址,然后转向相应的函数地址表。友元不能是虚函数,因为不是类成员。
纯虚函数提供未实现的函数,在末尾加上=0。包含纯虚函数的类只用作基类,不能创建对象。
当基类和派生类都采用动态内存分配时,派生类的析构函数,复制构造函数,赋值运算符都必须使用相应的基类方法来处理基类元素。
第14章
valarray类是一种模板类,必须声明数据类型,例如:
valarray<int> value或者数组:valarray<double> v(8)
。它有一些方法可以访问数据:operator[ ] ( ), size(), sum(), max(), min().私有继承:
- 私有继承和包含的不同是初始化时私有使用的是类名。
- 私有继承需要用类名和作用域解析符来调用基类方法。
- 私有继承的派生类可以强制类型转换后访问基类对象。
- 私有继承中,在不进行显示类型转换的情况下,不能将指向派生类的引用或指针赋给基类引用或指针。
各个继承关系:
特征 | 公有继承 | 保护继承 | 私有继承 |
---|---|---|---|
公有成员变成 | 公有 | 保护 | 私有 |
保护成员变成 | 保护 | 保护 | 私有 |
私有成员变成 | 只能通过基类接口访问 | 只能通过基类接口访问 | 只能通过基类接口访问 |
能否隐式向上转换 | 是 | 是(但只能在派生类的定义中) | 否 |
隐式向上转换意味着可以不显式类型转换就可以将基类指针或引用指向派生类对象。
若要基类方法在派生类外可用:
方法一:在派生类中定义一个使用基类方法的派生类方法。
方法二:使用using来指定派生类可以使用的特定基类成员。虚基类使得多个共同基类的派生类派生出的对象只继承一个基类对象。
class singer : public virtual worker{ }
或者class singer : virtual public worker{ }
基类是虚的时候,禁止信息通过中间类自动传递给基类,所以不希望默认构造函数来构造虚基类对象,则需要显式调用所需基类构造函数。正确构造函数写法:
SingingWaiter(const Worker & wk, int p = 0, int v = other)
: Worker(wk), Waiter(wk,p), Singer(wk,v) {}
要注意虚类的二义性的问题。
模板类:
在类的定义前template <class Type>
或者template <typename Type>
。在方法中使用类名加<Type>
限定。例如Stack类:
template <class Type>
Stack<Type>::Stack()
{
top = 0;
}
模板表达式里可以是整型,枚举,引用或指针,并且可以提供默认值。
模板类同样有隐式实例化,显式实例化和显式具体化:
隐式实例化ArrayTp<string, 100> stuff
显式实例化template class ArrayTp<string, 100>
显式具体化:template <> class SortedArray<const char *>{ }
如果模板有多个类型,可以只部分具体化,编译器会选择具体化最高的模板。
模板可以嵌套:
template <typename T>
template <typename V>
模板可以作为参数:
template <template <typename T> class Thing>
,其中template <typename T> class
是类型,Thing是参数。模板类可以用于友元函数。