1.在数组与多态混用的情况下,数组元素的访问会出现不可预期的结果(因为数组元素的访问会使用到下标运算)

将一个子类对象数组传递给一个父类对象数组声明的函数,编译器会允许这个行为,但是由于子类对象和父类对象的内存结构不同,会导致运行结果异常,因为在这种情况下,编译器仍然假设每一个元素的大小是父类对象元素的大小,但此时实际上每一个元素的大小是子类对象元素的大小

#include<bits/stdc++.h>
using namespace std; class BST
{
public:
char c;
}; class balancedBST:public BST//公有继承
{
public:
int x;
}; void printBSTArray(ostream& s,const BST array[],int numElements)//打印基类数组,注意数组的类型为基类!
{
for(int i=0;i<numElements;i++)
s<<array[i].c;
s<<endl;
} int main()
{
BST array[3];
for(int i=0;i<3;i++)
array[i].c='A'+i; printBSTArray(cout,array,3);//传递进入函数的是基类数组,打印正常 balancedBST barray[3];
for(int i=0;i<3;i++)
{
barray[i].x=i+1;
barray[i].c='a'+i;
} printBSTArray(cout,barray,3);//传递进入函数的是子类数组,打印异常!
/*
异常的原因:
因为函数定义的时候该对象的数组定义的是为基类类型,所以编译器在后续的操作中,
无论传入函数的是基类对象数组还是子类对象数组,都将视为基类对象数组
而基类对象的内存结构和子类对象的内存结构是不一样的
这样,通过下标访问到的东西,其实不是你想访问的东西 array[i] *(array+i)
array[0]和array[i] 之间相隔 i*sizeof(BST) 函数是按照i*sizeof(BST)算的,而如果你传入的是基类对象数组,也按照这样算的话,肯定是访问不到你想要的东西的
*/ } /*
运行结果:
ABC
ai
*/

2.在多态与数组混用的情况下,数组元素的删除也存在问题,会使用到没有定义的操作(通过基类指针来删除子类对象数组的行为在C++中是未定义的!)

#include<bits/stdc++.h>
using namespace std; class BST
{
public:
char c;
}; class balancedBST:public BST//公有继承
{
public:
int x;
}; void deleteArray(ostream& logStream,BST array[])
{
logStream<<"Deleting array at adress: "<<static_cast<void*>(array)<<endl;
delete [] array;//该操作的底层其实使用了下标,如果传入的是子类对象数组,那么通过基类指针来删除子类对象数组的行为在C++中是未定义的!
} int main()
{
BST *array =new BST[3];
balancedBST *barray =new balancedBST[3]; deleteArray(cout,array);//传入的是基类对象 deleteArray(cout,barray);//传入的是子类对象,存在问题,底层使用了未定义的操作
}

总结:那么如何避免上述两种问题呢?

第一个办法是避免采用多态方式来处理数组

第二个方法是避免让一共具体类继承自另外一个具体类

【More Effective C++ 条款3】最好不要以多态方式处理数组的更多相关文章

  1. [More Effective C++]条款22有关返回值优化的验证结果

    (这里的验证结果是针对返回值优化的,其实和条款22本身所说的,考虑以操作符复合形式(op=)取代其独身形式(op),关系不大.书生注) 在[More Effective C++]条款22的最后,在返回 ...

  2. More Effective C++ 条款0,1

    More Effective C++ 条款0,1 条款0 关于编译器 不同的编译器支持C++的特性能力不同.有些编译器不支持bool类型,此时可用 enum bool{false, true};枚举类 ...

  3. Effective C++ 条款08:别让异常逃离析构函数

    1.别让异常逃离析构函数的原因 <Effective C++>第三版中条款08建议不要在析构函数中抛出异常,原因是C++异常机制不能同时处理两个或两个以上的异常.多个异常同时存在的情况下, ...

  4. Effective C++ -----条款28:避免返回handles指向对象内部成分

    避免返回handles(包括reference.指针.迭代器)指向对象内部.遵守这个条款可增加封装性,帮助const成员函数的行为像个const,并将发生“虚吊号码牌”(dangling handle ...

  5. Effective C++ -----条款21:必须返回对象时,别妄想返回其reference

    绝不要返回pointer或reference指向一个local stack对象,或返回reference指向一个heap-allocated对象,或返回pointer或reference指向一个loc ...

  6. Effective C++ -----条款19:设计class犹如设计type

    Class的设计就是type的设计.在定义一个新type之前,请确定你已经考虑过本条款覆盖的所有讨论主题. 新type的对象应该如何被创建和销毁? 对象的初始化和对象的赋值该有什么样的区别? 新typ ...

  7. Effective C++ -----条款18:让接口容易被正确使用,不易被误用

    好的接口很容易被正确使用,不容易被误用.你应该在你IDE所有接口中努力达成这些性质. “促进正确使用”的办法包括接口的一致性,以及与内置类型的行为兼容. “阻止误用"的办法包括建立新类型.限 ...

  8. Effective C++:条款27——条款

    条款27:尽量少做转型动作 单一对象可能拥有一个以上的地址!

  9. Effective C++ 条款45

    本节条款的题目是运用成员模板接受全部兼容类型 作者阐述自己的观点是通过智能指针的样例. 在学习本节条款之前我们要先明确关于隐式转化的问题 例如以下代码: #include<iostream> ...

随机推荐

  1. var变量

    # Aduthor:CCIP-Ma name = "ma" name2 = name name = "ccip-ma" print("My name ...

  2. HDFS基本原理

    一.什么是HDFS HDFS即Hadoop分布式文件系统(Hadoop Distributed Filesystem),以流式数据访问模式来存储超大文件,它和现有的分布式文件系统有很多共同点.但同时, ...

  3. python 检查站点是否可以访问

    最近碰到系统有时候会访问不了,想写一个程序来检测站点是不是可以访问的功能,正好在学python,于是写了一个方法来练练手,直接上代码. import urllib.request import smt ...

  4. ActiveMQ反序列化(CVE-2015-5254) && ActiveMQ任意文件写入 (CVE-2016-3088)

    ActiveMQ 反序列化漏洞(CVE-2015-5254) 漏洞详情 ActiveMQ启动后,将监听61616和8161两个端口,其中消息在61616这个端口进行传递,使用ActiveMQ这个中间件 ...

  5. 英语cartialgenous鹿茸cartialgenous单词

    鹿茸cartialgenous是雄鹿未骨化密生茸毛的幼角,主要从梅花鹿和马鹿头上采收,前者叫花鹿茸.黄毛茸,后者叫青毛茸.雄鹿到了一定年纪头上就会长角,初发时嫩如春笋,其表面上有一层纤细茸毛的嫩角就是 ...

  6. CATransform3D 特效详解

    http://blog.sina.com.cn/s/blog_8f5097be0101b91z.html

  7. c++ win32下窗口的最小化到托盘以及还原

    框架是用visual studio创建的win32控制台模板,然后自己添加最小化及还原部分代码. 需要额外包含的头文件: #include <shellapi.h> #include &l ...

  8. AssetBundleMaster_Introduce_EN

    This is an integrated solution for building AssetBundles and loading Assets. what it can do is about ...

  9. jmeter压测学习4-正则表达式提取

    前言 上一个接口返回的token作为下个接口的入参,除了前面一篇讲到的用json提取器提取,也可以用正则提取. json提取器只能提取json格式的数据,正则可以匹配任意的返回. 我现在有一个登陆接口 ...

  10. nodejs接收post请求参数

    原文 https://blog.csdn.net/u013263917/article/details/78682270#1.2 nodejs接收post请求参数1.1-浏览器发送post请求参数的方 ...