多态
继承的最重要性质之一:
可以通过指向基类的指针或引用,来操作派生类对象/数组。
多态和指针算术不能混用
举例说明:
class BST{};
class BalancedBST : public BST {} //继承
//打印BSTs数组中的每一个BST的内容
void printBSTArray(ostream &s, const BST array[],
int numElements)
{
for(int i = 0; i < numElements;)
{
s << array[i]; //假设BST类重载operator<<可用
}
}
//情况(1)
//将一个由BST对象组成的数组传给printBSTArray函数
BST BSTArray[10];
...
printBSTArray(cout, BSTArray, 10); //运行良好
//情况(2)
//将一个由BalancedBST对象组成的数组传给printBSTArray函数
BalancedBST bBSTArray[10];
...
printBSTArray(cout, bBSTArray, 10); //运行正常吗?
注意:
for(int i = 0; i < numElements;)
{
s << array[i];
}
array[i]是一个“指针算数表达式”的缩写:
- array是个指针,指向数组起始处;
- array[i] 代表的其实是 * (array + i);
- array所指内存和array+i所指的内存两者相距多远?答案是 i*sizeof(数组中的对象);
- array[0]和array[i]之间有i个对象。
- 显然!参数array被声明为“类型为BST”的数组,即array[0]和array[i]之间的距离必是i * sizeof(BST);
- 但是!由于派生类通常比其基类有更多的data members,所以子类对象都比基类对象大得多;
- 因此!我们我们合理地预期一个BalancedBST对象比一个BST对象大,编译器为printBSTArray函数所产生的指针算数表达式array[i]对于BalancedBST对象所组成的数组而言就是
错误的。
总结
绝对不要以多态方式处理数组,多态和指针算数不能混用。