03. 绝对不要以多态(polymorphically)方式处理数组
继承的最重要性质之一就是:可以通过"指向base class objects"的pointers和references,来操作derived class objects。如此的pointers和references,其行为是多态的。
有如下例子:
class BST{...};
class BalanceBST : public BST{...};
考虑有个函数,打印BSTs数组中的每一个BST的内容:
void PrintBSTArray(ostream& s, const BST array[], int numElements)
{for (int i = 0; i < numElements; ++i){s << array[i];}
}
当你将一个BST对象的数组传给此函数,没问题:
BST bstArray[10];
...
PrintBSTArray(cout, bstArray, 10); // 良好运行
但是如果将一个BalanceBST组成的数组传给此函数:
BalanceBST bstArray[10];
...
PrintBSTArray(cout, bstArray, 10); // 未定义行为
行为未定义。这是因为PrintBSTArray函数时,使用下标i访问array涉及到对数组array的处理(array[i] = *(array + i))
。array是个指针,指向数组起始处。array所指内存和array + i
相距多远?是i * sizeof(数组中的对象)
。它会将传入的数组都处理成BST类型,因为其函数声明中array就是BST类型,这里不会有虚函数类似的处理。
如果你尝试删除数组,依旧传入BalanceBST数组
void DeleteArray(ostream& logStream, BST array[])
{...delete [] array;
}
BalanceBST* pArray = new Balance[50];
...
delete [] pArray;
虽然看不到,但其中依旧有指针运算表达式的存在。实际有如下处理:
for (int i the number of elements in the array - 1; i >= 0; --i)
{array[i].BST::~BST(); // 调用array[i]的destructor
}
错误原因同上。
总结
通过base class指针删除一个有derived classes objects构成的数组,其结果未定义。多态和指针算术不能混用,数组对象几乎总是会涉及到指针的算数运算,所以数组和指针不能混用。
03. 绝对不要以多态(polymorphically)方式处理数组相关推荐
- 笔记整理1----Java语言基础(一)01 变量与数据类型+02 运算符与表达式+03 条件判断与循环语句+04 JAVA数组+05 函数与方法
01 变量与数据类型+02 运算符与表达式+03 条件判断与循环语句+04 JAVA数组+05 函数与方法 第01天 java基础知识 今日内容介绍 Java概述.helloworld案例 工 ...
- 创建一个二维数组,以4行4列左对齐的方式将数组输出
创建一个二维数组,以4行4列左对齐的方式将数组输出 package p1;public class Java_2{public static void main(String[] args){//** ...
- 指针数组下标JAVA_Java语言中可用下标和指针两种方式表示数组元素。
[判断题]一行可以写多条预处理命令 [判断题]如果一个java程序中有多个类,编译后只生成一个字节码文件,其名字同主类名一致. [判断题]Protected类型的实例变量只能在本类中使用,其他类中不可 ...
- 017循环的方式定义数组、018循环for each、019方法练习、020实参和形参、021方法的返回值
017循环的方式定义数组 using System;namespace _017循环的方式定义数组 {class Program{static void Main(string[] args){// ...
- http url get方式传递数组参数
此文为自己记录,请大家指教 URL 通过Get方式传递数组参数 方法1: ?id=1&id=2&id=3 注意:Get 方式有字数限制 后台获取时,只需要reqeust.getPara ...
- 第二十九节:Java基础知识-类,多态,Object,数组和字符串
前言 Java基础知识-类,多态,Object,数组和字符串,回顾,继承,类的多态性,多态,向上转型和向下转型,Object,数组,多维数组,字符串,字符串比较. 回顾 类的定义格式: [类的修饰符] ...
- JavaScript - 用对象的方式创建数组
<html><head><head><body><script language="javascript">// 用对象 ...
- c51汇编语言读写idata,汇编语言用[bx+idata]的方式进行数组的处理
在前面,我们用[bx]的方式来指明一个内存单元,还可以用一种更为灵活的方式来指明内存单元:[bx+idata]表示一个内存单元,它的偏移地址为(bx)+idata(bx中的数值加上 idata) 我们 ...
- 一个简单的方式打印数组中的所有值
用简单的方式打印数组中的所有值,即利用 Arrays类的 tostring方法. 调用 Arrays.toString(a),返回一个包含数组元素的字符串,这些元素被放置在括号内,用逗号分隔. 要想打 ...
- 用最复杂的方式学会数组(Python实现动态数组)
聊聊Python序列类型的本质 在本博客中,我们来聊聊探讨Python的各种"序列"类,内置的三大常用数据结构--列表类(list).元组类(tuple)和字符串类(str)的本质 ...
最新文章
- C#的方法的参数修饰符详解
- 【Android 应用开发】Android 开发错误集锦
- 深度学习练手项目(一)-----利用PyTorch实现MNIST手写数字识别
- 都是基于.NET平台,WPF能取代Winform吗?
- await,async 我要把它翻个底朝天,这回你总该明白了吧
- 组装复杂json请求数据和解析复杂json数据
- B00012 C++算法库的sort()函数
- mysql的binary安装
- VS2017离线下载 -- 如何让VS2017不占用C盘
- linux命令查看系统日期,Linux系统查看当前时间的命令
- ABAQUS混凝土CDP插件,一键生成混凝土CDP本构曲线
- 我在Facebook干不下去的10个理由
- poi操作word替换文本框里的内容
- paddleocr cpp_infer 操作说明
- 上古卷轴5捏脸php导入,上古卷轴5捏脸预设导入 上古卷轴5捏脸预设怎么导入
- Android N Android O 默认MTP模式 实时文件扫描
- 计算机网络8832,3C8832路由器中DDN中的应用设置
- Cisco_NBAR封杀BT和电驴下载
- (转)Word2016怎么和mathtype兼容
- 【U8+】用友U8+对账不平案例及方法总结
热门文章
- 深度学习课程笔记(十三)深度强化学习 --- 策略梯度方法(Policy Gradient Methods)...
- hadoop完全分布式集群下安装sqoop
- 多线程编程-之并发编程:同步容器
- 泛函编程(7)-数据结构-List-折叠算法
- Strom 可定制任务调度策略(Pluggable Scheduler)
- SharePoint 2013技巧分享系列 - 隐藏Blog和Apps左侧导航菜单
- C++primer笔记之顺序容器
- Kruskal/Prim/Dijkstra模板
- 2.Linux 高性能服务器编程 --- IP 协议详解
- mysql 批量更新_MySQL批量更新