- 绝对不要以多态方式处理数组
继承的一个重要性质为:通过父类的指针或者引用来操作子类对象。同时c++也允许你通过父类的指针或者引用来操作子类对象所形成的数组,但是这并不会如你所预料那样般的运作。
class BST{};
class BalancedBST:PUblic:BST{};
void printBSTarray(ostream&os,const BST array[],int numelements){
for(int i=0;i<numelements;++i){
s<<array[i];
}
}
BST BSTarray[10];
printBSTarray(cout,BSTarray,10)//运行良好
BalancedBST bBSTarray[10];
printBSTarray(cout,bBSTARRAY[10],10);//结果不可预期
//array[i]其实是一个指针算术表达式,,它代表的是*(array+i),array是一个指针。array所指内存到array+i所指内存的大小为i*sizeof(数组对象的大小),为了让编译器所产生的代码正确走访整个数组,编译器必须有能力决定数组对象的大小。对于上面的这个函数我们的array的参数被指定为BST的对象,所以数组中的每个元素必然是BST对象的大小。但是当我们传入BalanceBST的对象的时候,编译器误以为我们还是传入的BST的对象,而BlanceBST的对象的大小远比BST的对象大。所以PrintBSTarray所产生的指针算术表达式对于BalanceBST对象来说就是错误的。所以结果不可预期。
//当我们以一个基类指针来删除子类数组的时候也会发生这样的错误,因为它还会使用指针算术表达式
void deletearray(ostream& os,BST array[]){
...
delete[]array;
}
//当你调用这个函数的时候delete会调用以下代码
for(int i=numelements;i>=0;--i){
array[i].BST::~BST{};//行为错误的循环,c++语言规范说,使用一个基类指针删除基类对象构成的数组,结果未定义
}
总结:多态与数组不要混用,同时具体类不要继承自另一个具体类(下节讲)