酱坛子

专注C++技术 在这里写下自己的学习心得 感悟 和大家讨论 共同进步(欢迎批评!!!)

  C++博客 :: 首页 :: 联系 :: 聚合  :: 管理
  66 Posts :: 16 Stories :: 236 Comments :: 0 Trackbacks

公告

王一伟 湖南商学院毕业 电子信息工程专业

常用链接

留言簿(19)

我参与的团队

搜索

  •  

积分与排名

  • 积分 - 382420
  • 排名 - 63

最新随笔

最新评论

阅读排行榜

评论排行榜

inheritance的重要性质就是你可以通过指向base class objects的pointers或者references来操作derived class object.

同样C++也允许你使用pointers或者references来操作derived class object形成的数组。但是这样的行为很危险,几乎不会按你设定的方式运作。

我们来举个例子:

 class A{};
 class B:public A{};

 //现在我们有一个函数
void printAArray(ostream& s,const A array[],int numElement)
{
   
    for(int i=0;i<numElement;++i)
      
{
            s
<<array[i];//假设A objects中有一个operator<<可以用 
 
     }

}


当你把A AArray[10];传给他
...
printAArray(cout,AArray,10);//运作良好

但是当你把B BArray传给他
printAArray(cout,BArray,10);//还能正常运作吗

毫无疑问,编译时编译器会很开心的接受他。但是运行时呢
 for(int i=0;i<numElement;++i)
  
{
            s
<<array[i];//假设A objects中有一个operator<<可以用 
 
}
就会出问题,array所指向的内存和array+i所指向的内存有多远的距离
答案是i*sizeof(A),但是我们在穿BArray的时候我们需要的是i*sizeof(B),因为
derived class object通常比base class object 大。

同样你通过bass class来删除derived class object的时候,都会产生不可预期的错误

简单的说,大家需要注意的一点就是,数组不要和多态进行混合使用,因为数组总是会涉及指针
的算术运算。

当然这个也不是绝对的,都是内存访问惹的祸

如果你能够避免一个具象类(带有参数的类)继承自另外的一个具象类,你就不太能犯
下这样的错误。

具体的内容我晚上在下一篇随笔里面进行介绍
posted on 2007-01-31 09:44 @王一伟 阅读(1401) 评论(7)  编辑 收藏 引用

Feedback

# re: 不要使用polymorphically方式处理数组 2007-01-31 23:23 Elvis
个人觉得这是一个典型的对象切片~A AArray[10]中的10个A对象的实例是分配在栈上的静态对象,而不是分配在堆上的动态对象吧~这样的话其实就不存在多态了,因为多态是对指针对象而言的,于是当将子类对象赋给基类对象时,对象切片就发生了~  回复  更多评论
  

# re: 不要使用polymorphically方式处理数组 2007-02-01 11:23 王一伟
不是吧,栈内我还是可以调用函数的,再入栈一次就是了,我仍然可以使用指针方式进行参数传递。
确实,这个是一个切片现象。
呵呵
老兄 发觉这人好少啊 我想搬去csdn了 那人好多  回复  更多评论
  

# re: 不要使用polymorphically方式处理数组 2007-02-02 01:08 OOMusou
Elvis說的沒錯
很典型的Object Slicing
請看Effective C++ 條款20  回复  更多评论
  

# re: 不要使用polymorphically方式处理数组 2007-02-02 09:15 holyfire
这根本不是多态的运用方式,C++下使用多态要用基类指针的方式,看来你还需要加强下基础  回复  更多评论
  

# re: 不要使用polymorphically方式处理数组 2007-02-02 11:41 王一伟
恩,我马上去瞧瞧Effective C++ 条款20,汗 我还没看到那

但是这个不是多态需要的基类指针的方式我就表示怀疑了,
只要virtual了base class的destructor 感觉后面的问题就可以解决了

多谢大家关心,不过还是希望大家能详细点告诉我错在哪里 嘿嘿 基础差偶欢迎大家批评 呵呵 最近恶补基础


  回复  更多评论
  

# re: 不要使用polymorphically方式处理数组 2007-02-03 01:52 Elvis
PS:你说的这个问题在C++ CODING STANDARDS的第100条有论述~  回复  更多评论
  

# re: 不要使用polymorphically方式处理数组 2007-02-03 09:03 酱菜
呵呵 是的 Elvis兄

Don't treat arrays polymorphically

Pointers serve two purposes at the same time: that of monikers (small identifiers of objects), and that of array iterators (they can walk through arrays of objects using pointer arithmetic). As monikers, it makes a lot of sense to treat a pointer to Derived as a pointer to Base. As soon as the array iteration part enters the stage, however, such substitutability breaks down because an array of Derived isn't the same as an array of Base. To illustrate: Mice and elephants are both mammals, but that doesn't mean a convoy of a thousand elephants would be as long as one of a thousand mice.

Size does matter. When substituting a pointer to Derived to a pointer to Base, the compiler knows exactly how to adjust the pointer (if necessary) because it has enough information about both classes. However, when doing pointer arithmetic on a pointer p to Base, the compiler computes p[n] as *(p + n * sizeof(Base)), thus assuming that the objects lying in memory are all Base objectsand not objects of some derived type that might have a different size. Imagine, now, just how easy it is to tromp all over of an array of Derived if you convert the pointer marking its start to Base* (with compiler's silent approval) and then perform pointer arithmetic on that pointer (while the compiler doesn't blink an eye either)!

Such accidents are an unfortunate interaction between substitutability, which dictates that pointers to derived classes should be usable as pointers to their bases, and C's legacy pointer arithmetic, which assumes pointers are monomorphic and uses solely static information to compute strides.

To store arrays of polymorphic objects, you need an array (or, better still, a real container; see Item 77) of pointers to the base class (e.g., plain pointers or, better still, shared_ptrs; see Item 79). Then each pointer in the array refers to a polymorphic object, likely an object allocated on the free store. Or, if you want to expose an interface to a container of polymorphic objects, you need to encapsulate the entire array and offer a polymorphic interface for iteration.

Incidentally, a good reason to prefer references to pointers in interfaces is to make it clear that you're talking about one object, as opposed to possibly an array of them.
  回复  更多评论
  


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理