设为首页 加入收藏

TOP

14.6 派生类的数组
2013-10-07 15:06:13 来源: 作者: 【 】 浏览:76
Tags:14.6 派生

14.6  派生类的数组

这个被广泛描述的缺陷[Meye1996, Stro1997, Dewh2003]是C++(www.cppentry.com)最有问题的imperfections之一。如果你有一个父类Base,一个派生类Derived,它们的大小不同(也就是说,Derived的实例比Base的大),那么将Derived数组的指针传递给一个接受Base数组指针的函数就会导致不愉快的结果。因为这样一来除了数组的第一个元素(偏移量为0)能够对齐外,其余所有元素都不会对齐。这种情况下能够预期的最好结果就是一个干净利落的程序崩溃。考虑程序清单14.4中的代码:

程序清单14.4

  1. struct Base  
  2. {  
  3.   Base()  
  4.     : m_i0(0)  
  5.   {}  
  6.   int m_i0;  
  7. };  
  8.  
  9. void print_Base(Base &b)  
  10. {  
  11.   printf("%d ", b.m_i0);  
  12. }  
  13.  
  14. class Derived  
  15.   : public Base  
  16. {  
  17.   Derived()  
  18.     : m_i1(1)  
  19.   {}  
  20.   int m_i1;  
  21. };  
  22.  
  23. void print_array(Base ab[], size_t cb)  
  24. {  
  25.   for(Base *end = ab + cb; ab != end; ++ab)  
  26.   {  
  27.     print_Base(*ab); // 处理每一个元素  
  28.   }  
  29. }  
  30.  
  31. int main()  
  32. {  
  33.   Base    ab[10];  
  34.   Derived ad[10];  
  35.   print_array(ab, 10); // Ok  
  36.   print_array(ad, 10); // 编译通过并运行,但错误就在前方不远处守候着您!  
  37.   . . .  

在本例中,对print_array()的第一次调用会正确地打印出"0 0 0 0 0 0 0 0 0 0",然而第二次调用却会打印出"0 1 0 1 0 1 0 1 0 1"。实际上这比程序崩溃还要糟糕,因为如果程序的"病症"是像本例中的这种"良性"的话,bug就有可能引不起你的注意。幸运的是,在大多数实际的情况下,这种误用所导致的结果是程序崩溃。

人们可以争辩说这根本不能算是个imperfection, 只不过是C++(www.cppentry.com)对象模型所导致的结果而已[Lipp1996]。但它被忽视和误解的程度是如此频繁,导致的后果是如此危险,且编译器对其无法提供任何防卫性的措施,因此在我的评价中它被看成一个严重的imperfection。

Imperfection:C++(www.cppentry.com)的数组/指针二重性,加之对派生类型的多态性支持,导致了一个危险,并且编译器对此不提供任何帮助措施。

在本节的剩余部分,我们将会看到有关这个缺陷的几个局部的解决方案,以及用于避免该缺陷的技术,最后我们将看到一种用于表示数组形参的充分有效的技术。

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇14.6.1 通过指针保存多态类型 下一篇14.7 不能拥有多维数组

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: