第一章,基础议题

条款3 不要以多态方式处理数组

问题场景描述(1):

在C++中,可以通过指向基类的指针来操作派生类对象,这个指针就好像有多重类型一样,原著笔者在这里称将其也称为多态,这种多态操作方式应该避免数组操作,概括一下是因为基类和派生类的成员很可能是不一样的,这也就意味着他们的对象大小是不一样的,而数组arr[i]的调用就相当于*(arr+i*sizeof(object)),这个i的步进值取决于元素的大小,因此会引发“未定义”错误

class BST{...};
class BalancedBST : public BST{...};

void printBSTArray(ostream& s, const BST array[],int numElements)
{
for(int i = 0; i < numElements; i++)
s << array[i];
}

BST BSTArray[10];
printBSTArray(BSTArray);//All Right!

BalancedBST bStArray[10];
printBSTArray(bStArray);//编译器会被误导,认为实际的数组元素大小是sizeof(BST),但是实际的大小却是sizeof(BalancedBST)

问题场景描述(2):

当尝试通过基类型指针删除一个由派生类对象组成的数组时,问题(1)会以另一种形式出现:

class BST{...};
class BalancedBST : public BST{...};

void deleteArray(ostream& logStream, BST array[])
{
logStream << "Deleting array at address " << static_cast<void*>(array) << '\n';
delete[] array;
}

BalancedBST bStArray[10];
deleteArray(bStArray);//实际会调用array[i].BST::~BST();析构;通过基类型指针删除派生类类型数组会发生未定义结果;

注意: 应该避免继承具体类