多态指的是可以通过基类类型的指针或引用, 来操作派生类的对象. 然而通过基类类型的指针或引用,来操作派生类的对象数组, 则没有任何保证如预期般运作.
有一个class BST以及继承自BST的class BalancedBST:
class BST
{
public:
BST():bst1(-1),bst2(-2){}
virtual ~BST(){cout << "BST::~BST" << endl;}
virtual ostream& operator<<(ostream& os) const
{
os << "BST::operator<<:" << bst1 << "," << bst2 << endl;
return os;
}
private:
int bst1;
int bst2;
};
class BalancedBST: public BST
{
public:
BalancedBST():bbst1(1), bbst2(2){}
virtual ~BalancedBST(){cout << "BalancedBST::~BalancedBST" << endl;}
virtual ostream& operator<<(ostream& os) const
{
os << "BalancedBST::operator<<:" << bbst1 << "," << bbst2 << endl;
return os;
}
private:
int bbst1;
int bbst2;
};
为了让输出BST类族, 惯用 cout< 然后通过遍历指向基类的指针或引用(数组名作为函数参数会被退化为基类对象数组首地址): 经运行“以基类类型的指针,来操作派生类的对象数组“会发生crash, 而“以基类类型的指针,来操作基类的对象数组“则没有问题: 这是因为array[i]代表 *(array+i), 在编译阶段编译器便静态决定了数组中的每个对象大小, 只会以固定 sizeof(BST)进行指针的移动. 而通常带有数据成员的派生类的大小和基类通常不同, 编译器所产生的指针算数表达式对派生类对象数组是错误的, 结果不可预期. 同样, C++规范说通过基类的指针删除派生类对象数组, 结果也是未定义的: 结果:ostream& operator<<(ostream& os, const BST& bst)
{
bst << os;
return os;
}
void printBSTArray1(ostream& s, const BST array[], int numEles)
{
cout << "printBSTArray1:" << endl;
for (int i = 0; i < numEles; ++i) {
array[i]<
BST BSTArray[10];
BalancedBST BalancedBSTArray[10];
printBSTArray1(cout, BSTArray, 10); //ok
printBSTArray1(cout, BalancedBSTArray, 10); //crash
void deleteArray(ostream& logstream, BST array[])
{
logstream << "deleting array at address " << static_cast
BalancedBST::~BalancedBST
BST::~BST
===============
deleting array at address 0x100705688
BST::~BST
BST::~BST
BST::~BST
BST::~BST



