条款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的妙妙屋!