栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

More Effective C++ (3)笔记之不要期望以多态处理数组 & 重载<<操作符

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

More Effective C++ (3)笔记之不要期望以多态处理数组 & 重载<<操作符

多态指的是可以通过基类类型的指针或引用, 来操作派生类的对象. 然而通过基类类型的指针或引用,来操作派生类的对象数组, 则没有任何保证如预期般运作.

有一个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<

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]< 

经运行“以基类类型的指针,来操作派生类的对象数组“会发生crash, 而“以基类类型的指针,来操作基类的对象数组“则没有问题:

BST BSTArray[10];
BalancedBST BalancedBSTArray[10];

printBSTArray1(cout, BSTArray, 10);           //ok
printBSTArray1(cout, BalancedBSTArray, 10);   //crash

这是因为array[i]代表 *(array+i), 在编译阶段编译器便静态决定了数组中的每个对象大小, 只会以固定 sizeof(BST)进行指针的移动. 而通常带有数据成员的派生类的大小和基类通常不同, 编译器所产生的指针算数表达式对派生类对象数组是错误的, 结果不可预期.

同样, C++规范说通过基类的指针删除派生类对象数组, 结果也是未定义的:

void deleteArray(ostream& logstream, BST array[])
{
    logstream << "deleting array at address " << static_cast(array) << endl;
    delete [] array;
}

BST* balTree = new BalancedBST;
delete balTree;

cout << "===============" << endl;

BalancedBST* balTreeArray = new BalancedBST[4];
deleteArray(cout, balTreeArray);

结果:

BalancedBST::~BalancedBST
BST::~BST
===============
deleting array at address 0x100705688
BST::~BST
BST::~BST
BST::~BST
BST::~BST
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/886589.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号