读《More Effective C++35个改善编程与设计的有效方法》之条款3:绝对不要以多态方式处理数组

来源:互联网 发布:开源crm软件著作权 编辑:程序博客网 时间:2024/06/05 11:58

有以下程序:

<pre name="code" class="cpp">class Base{public:Base(int n = 0) : _b(n) {}int _b;};class Devide : public Base{public:Devide(int n = 0, int m = 0) : Base(n), _d(m) {}int _d;int _d1;};void print(std::ostream& s, const Base array[], int num){for (int i = 0; i < num; ++i)s << array[i]._b << std::endl;}


在主函数中这么调用:

Base b1[10];print(std::cout, b1, 10);
运行结果如下:

结果是正确的,但是如果我以如下方式运行:

Devide d[10];print(std::cout, d, 10);
会发生什么呢?


结果有些却是不对的。更确切的说,是未定义呢。

为什么呢。

因为我们都知道数组array[i]是一个指针算术表达式,它的地址是*(array+i),array是指针,指向数组起始处,所以array+i,所指的内存,就应该是array+i*sizeof(对象),那么这边的对象是什么呢,我们声明的是Base对象,即使我们传过来的是Devide的对象,所以,array+i的地址就是array+i*sizeof(Base),但是其实它的大小是Devide的大小,所以很明显,除了第一个,后面的地址,都是错误的。如果我把Devide的成员函数的值赋值一下,结果就不一样了。

所以,绝对不能以多态的方式来处理数组,否则会让你“大吃一惊的”。


0 0