条款03:不以多态的性质处理数组
1️⃣ 继承
- 继承的最重要性质就是:可以通过“指向
base class objects”的pointers或references,来操作derived class objects。如此的pointers和references,我们说其行为是多态的。
2️⃣ 问题
- C++允许你通过
base class的pointers和references来操作“derived class objects“所形成的数组。
3️⃣ 例子
1 | class BST { ... }; |
1 | void printBSTArray(ostream& s, const BST array[], int numElements) |
🔹 当给这个函数传递一个由 BST 对象组成的数组,代码不会产生问题。
1 | BST BSTArray[10]; |
🔸 当给这个函数传递一个由 BalanceBST 对象组成的数组,编译器不会发生报错,但是代码并不是我们想象的那样。
1 | BalnaceBST bBSTArray[10]; |
4️⃣ 解析
array[i]等价于*(array+i)。array是个指针,指向数组起始处。array所指内存和array+i所指内存两者相距多远?答案是i*sizeof(数组中的对象)。因为array[0]和array[i]之间有i个对象。- 为了让编译器所产生的代码能够正确走访整个数组,编译器必须决定数组中的对象大小。由于参数
array被声明成“类型为BST”的数组吗?所以数组中的每个元素必然都是BST对象,所以array和array+i之间的距离一定是i*sizeof(BST)。 - 但如果交给
printBSTArray函数一个由BalancedBST对象组成的数组,编译器就会被误导。这种情况下它仍假设数组中每一元素的大小是BST的大小,但其实每一元素的大小是BalancedBST的大小。由于derived classes通常比base classes大,因此,我们可以合理地预期一个BalancedBSTobject比一个BSTobject大。如果是这样,编译器为printBSTArray函数所产生的指针算术表达式,对于BalancedBST objects所组成的数组而言就是错误的。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 GYu的妙妙屋!
