【M3】绝对不要以多态方式处理数组
1、考虑下面的情况,有个方法,如下:
void Print(ostream& s, const Base array[], int size)
{
for(int i=0; i< size; ++i)
{
s<<array[i];
}
}
2、对于Base baseArray[10]; Print(cout, baseArray, 10) 没有问题。在C++中,子类对象组成的数组,可以复制给父类的引用或者指针。数组名也可以认为是个地址。
考虑: Derived derivedArray[10]; Print(cout, derivedArray, 10) 会发生什么事?
我们知道array[i] 其实就是 *(array +i ); 也就是移动i个单元,解引用。编译器必须知道移动多少个字节,既然方法声明中为父类数组,移动的字节就是 i*sizeof(Base).
当我们把子类对象组成的数组,传递给Print方法的时候,编译器还是按照 i*sizeof(Base)的方式移动。由于子类对象往往比父类对象大,造成的结果不可预期。
3、考虑方法
deleteArray(Base array[])
{
delete [] array;
}
delete [] array做的事情是:逆序对每个元素执行析构方法 Base::~Base(); 并且释放内存。当我们把子类对象组成的数组,传递给deleteArrayt方法的时候,编译器还是按照上面的方式处理,这必然导致未定义的行为。
4、结论就是:绝对不要以多态方式处理数组。
【M3】绝对不要以多态方式处理数组的更多相关文章
- C++以多态方式处理数组可能会遇到的问题
今天读<More Effective C++>时遇到一个条款:绝对不要以多态方式处理数组.以前自己也没有注意过,觉得有必要记录下来. C++是允许通过base class的指针或引用来操作 ...
- 【More Effective C++ 条款3】最好不要以多态方式处理数组
1.在数组与多态混用的情况下,数组元素的访问会出现不可预期的结果(因为数组元素的访问会使用到下标运算) 将一个子类对象数组传递给一个父类对象数组声明的函数,编译器会允许这个行为,但是由于子类对象和父类 ...
- 在ASP.NET MVC中以post方式传递数组参数的示例
最近在工作中用到了在ASP.NET MVC中以post方式传递数组参数的情况,记录下来,以供参考. 一.准备参数对象 在本例中,我会传递两个数组参数:一个字符串数组,一个自定义对象数组.这个自定义对象 ...
- URL 通过Get方式传递数组参数
URL 通过Get方式传递数组参数 方法1: ?id=1&id=2&id=3 后台获取时,只需要reqeust.getParameterValues("id") 获 ...
- 出于性能考虑,C语言自动地以传地址的方式将数组传递给被调函数 const 编译错误 最小权限原则
#include <stdio.h> int main(void) { char array[5]; printf("array=%p,&array[0]=%p,& ...
- 在ASP.NET MVC中以post方式传递数组参数的示例【转】
最近在工作中用到了在ASP.NET MVC中以post方式传递数组参数的情况,记录下来,以供参考. 一.准备参数对象 在本例中,我会传递两个数组参数:一个字符串数组,一个自定义对象数组.这个自定义对象 ...
- 用最复杂的方式学会数组(Python实现动态数组)
Python序列类型 在本博客中,我们将学习探讨Python的各种"序列"类,内置的三大常用数据结构--列表类(list).元组类(tuple)和字符串类(str). 不知道你发现 ...
- 以forin的方式遍历数组时进行删除操作的注意点
今天在修改某项需求的时候,需要在遍历的时候将匹配项移除掉,采用的时forin的方式遍历,然后运行的时候却crash掉了 for (NSString*str in self.btnArray) { if ...
- [汇编语言]-第七章 用[bx+idata]的方式进行数组的处理
1- 转化为大写 方法一: assume cs:code,ds:data data segment db 'BaSiC' db 'MinIX' data ends code segment start ...
随机推荐
- 浅析基层检察院派驻乡镇检察室的健康发展 z
时间:2011-03-22 10:08 作者:祝志方 新闻来源:正义网 一.前言 在我国,基层检察院派驻乡镇检察室的发展经过了一个曲折发展的历程,上世纪80年代,随着经济社会的发展,一批乡镇检察室应运 ...
- 转载: Vim 练级攻略
转自:http://coolshell.cn/articles/5426.html 酷壳 vim的学习曲线相当的大(参看各种文本编辑器的学习曲线),所以,如果你一开始看到的是一大堆VIM的命令分类, ...
- SQL Server2005安装配置以及测试
SQL Server2005有2种版本,一种是集成版的, 一种是2个文件夹形式的.这里使用后者,安装文件夹名字为:SQL Server x86,该文件夹里面有Servers和Tools文件夹以及一些其 ...
- Nonlinear Transform
前文中,我们已经学习了linear classification,linear regression,logistic regression三种线性方法. 如何解决这种问题呢? 其实很好解决,只需要加 ...
- 线性方法用于Binary clssification
到现在,我们已经学过三种线性方法:linear classification.Linear Regression.logistic Regression.这三种方法的核心都是,不同点在于:最小化的er ...
- MFC特定函数的应用20160720(SystemParametersInfo,GetWindowRect,WriteProfileString,GetSystemMetrics)
1.SystemParametersInfo函数可以获取和设置数量众多的windows系统参数 MFC中可以用 SystemParametersInfo(……) 函数来获取和设置系统信息,如下面例子所 ...
- Java学习笔记(3)
“当你定义出一组类的父型时,你可以用子型的任何类来填补任何需要或期待父型的位置” “运用多态时,引用类型可以是实际对象类型的父类”Animal myDog = new Dog(); 三种方法可以防止某 ...
- Static块详解
首先,我们先看一段程序,代码如下: public class Father { public Father() //构造方法 { System.out.println(" 父类构造方法&qu ...
- mysql repair data 语句
1. 这条语句主要是用来修复一个表中的数据 , 在另一个统计表中没有统计时,进行修改统计表的操作 update expert_count ec inner join ( select sum(e.EF ...
- libvirt虚拟系统如何增加usb设备
之前干这些事情都是通过virt-manager来搞定的.不过由于这个图形界面不太方便,而且现在没法打开(具体原因不详,每次打开提示一些方法未实现什么的),所以试下用libvirt的命令virsh来搞定 ...