春暖花开
雪化了,花开了,春天来了
posts - 149,comments - 125,trackbacks - 0

条款三 绝不要把多态应用于数组

继承的一大特性是,允许你通过指向基类的指针和引用来操纵派生类对象。也允许通过基类指针和引用来操纵派生类数组。

但是用基类指针操纵一个包含派生类对象的数组,就会发生各种个样的问题,其结果往往是不确定的。

我根据书中的例子,写了一个小程序:

#include <iostream>

using namespace std;

class BST
{
public:
    BST()
    
{
        i 
= 0;
    }

    
int i;
}
;

class BalancedBST: public BST
{
private:
    
int j;
}
;

void printBSTArray(ostream& outconst BST arr[], int numElements)
{
    
for (int i = 0; i < numElements; i++)
    
{
        
out << arr[i].i << endl;
    }

}


int main()
{
    cout 
<< "BST.\n";
    BST BSTArray[
10];
    printBSTArray(cout, BSTArray, 
10);

    cout 
<< "BalancedBST.\n";
    BalancedBST bBSTArray[
10];
    printBSTArray(cout, bBSTArray, 
10);

    system(
"pause");

    
return 0;
}


其结果如下:

 

 可以看到程序并不如我们所期望的那样,这说明什么呢?
 arr[i],表示的是*(arr+i),但是arr+i所指向的地址偏离arr所指向的地址是i*(an object in the array)。
因为参数被声明为BST数组类型,那么数组的每个元素必须是BST,那么它们的间隔也毕定是i*sizeof(BST)。如果传入BalancedBST数组,编译器可能就会犯错误,在这种情况下,编译器就会假定数组里每个对象的大小都和BST的大小一样。而通常派生类要比基类有更多的成员变量,所以派生类一般都比基类对象大。所以我们就看到了如上的结果。

 试图通过一个基类指针删除一个包含派生类对象的数组,也会有同样的问题。

所以不要把多台应用到数组上,还是很有好处的。

posted on 2009-09-22 11:57 Sandy 阅读(312) 评论(0)  编辑 收藏 引用 所属分类: c++学习

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理