首页
社区
课程
招聘
[旧帖] [求助]基成员的遮蔽(C++语言的设计和演化) 0.00雪花
发表于: 2011-6-18 10:14 1210

[旧帖] [求助]基成员的遮蔽(C++语言的设计和演化) 0.00雪花

2011-6-18 10:14
1210
Bjarne Stroustrup的《c++语言的设计和演化》,裘宗燕 译,机械工业出版社。
下面是原文:(蓝色)(问题在后面给出)
3.5.3 基成员的遮蔽
派生类里的名字将遮蔽基类中具有相同名字的任何对象或函数。这是不是一个好的设计决定,这件事称为许多年来争论的主题。这个规则最先是由带类的C引进的,我把它看作是普通作用域规则的必然推理。在有关这个问题的争论中,我一直认为与此相反的意见——将派生类和基类的名字合并到同一个作用域——至少会带来许多问题。特别是有可能错误地对子对象调用改变状态的函数:
class X {
     int x;
public:
     virtual void copy(X* p) {x = p->x;}
};

class XX: public X {
     int xx;
public:
    virtual void copy(XX* p) {xx = p->xx; X::copy(p);}
};

void f(X a, XX b)
{
    a.copy(&b);  //ok: copy X part of b
    b.copy(&a); //error: copy(X*) is hidden by copy(XX*)
}
如果合并了基类和派生类的作用域,那么第二个copy操作也就允许做了,而这将导致b的状态被部分更改的问题。大多数情况下这将导致对XX对象的操作出现非常奇怪的行为。我确实看到过人们被这种方式套住,他们使用的是GUN的C++编译系统,该编译系统允许这种重载。
   如果copy()是虚函数,我们可以认为XX::copy()覆盖了X::copy(),而这时就需要做运行时的检查才能捕捉到b.copy(&a)的问题,程序员也必须按防御的方式编程,以便在运行中捕捉到这种错误。当时已经理解了这种情况,但我害怕还有什么自己尚未理解的问题,因此就选择了现在这种最严格、最简单和最有效的规则。

问题:未能理解“虚函数”小节中的“基成员的遮蔽”,
1,为什么合并了基类和派生类的作用域,第二个copy操作就允许做了,这将导致b的状态被部分改变,如何改变的(请结合给出的例子)?
2,请给出你对原文的理解。
ps:我把c++ primer plus看了快两遍了,感觉自己实际能力还很不够,我该从哪方面入手来突破这一瓶颈。谢谢!

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (7)
雪    币: 191
活跃值: (130)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
2
这些书好像都没怎么看过 ,这个问题听说过,之前一直没碰到过,也期待详细解答
我这里就小小的YY一下,不妥的欢迎拍砖。
1,为什么合并了基类和派生类的作用域,第二个copy操作就允许做了,这将导致b的状态被部分改变,如何改变的(请结合给出的例子)?
b.copy(&a)可能你的本意是完成{xx = p->xx; X::copy(p);}
合并作用域后 b.copy(&a)  实际直接调用x::copy(x),


2,请给出你对原文的理解。
就是避免1的问题发生,如果真的要调用就用作用域的方式来操作,避免隐式转换造成作者说的奇怪的问题,使问题不太可控。为了避免因为参数类型不同而错误的调用其他基类中的,使问题复杂化,就采用了这种隐藏的方式处理。

BS的书都没怎么看,感觉涉及面太广,目前较难接受,我都看国产的比较好理解,先会简单使用,等熟悉了再好好看看,估计能看的稍微明白点吧,毕竟C++太博大了。也希望这方面经验多的,多给点指导性意见。
2011-6-18 14:34
0
雪    币: 24
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
这里的b的状态究竟指的是什么?!成员变量or其他什么东西。
1,如果是成员变量的话,那就奇怪了,我就是想要改派生类b或它的基类a的成员变量(即合并了基类和派生类的作用域),难道不行吗?
2.如是是其他什么东西的话,望大家共同指出。谢谢!
Attention,pls: 也许我提的问题本身就有问题或是错的。
2011-6-18 16:45
0
雪    币: 191
活跃值: (130)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
4
我水平确实有限,你说的那本书我也没看过,我认为是成员函数。
主要处理非虚表中的同名函数,这个是有域限制的(也就是隐藏)。
不知道LZ要实现什么功能,还是就跟这个规则卯上了。其他的我就没法回答你了,帮顶,待高手!
2011-6-18 17:25
0
雪    币: 24
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
我没有其他什么意思啊,呵呵!很感谢你能够回答(我还以为大家都不屑于回答这样的问题),我只是刚入门的那种。看过你写的文章,非常不错
2011-6-18 21:55
0
雪    币: 1708
活跃值: (586)
能力值: ( LV15,RANK:670 )
在线值:
发帖
回帖
粉丝
6
搜索 虚函数 多态性
2011-6-18 22:46
0
雪    币: 191
活跃值: (130)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
7
谢谢捧场,我也是刚刚接触不久,写的比较一般。
C++的东西太复杂了,我也是碰到需要的就查查, 这个规则主要我也不懂,也是现查资料学习的,有本"高质量C/C++"感觉不错。
2011-6-18 23:00
0
雪    币: 113
活跃值: (100)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
8
这本书我还真看过,虽然是很久前了。这段话的内容我能理解,楼主的问题不是很明白。:)

1. 假设合并了基类和派生类的作用域,这实际上就相当于2个函数的重载,
virtual void copy(X* p) {x = p->x;}
virtual void copy(XX* p) {xx = p->xx; X::copy(p);}
所以下面的动作得以通过,
b.copy(&a);
这会导致错误,因为copy的本义是复制一个对象的内容,而非复制部分。

2. BS担心这点,所以作出这样的设计 “派生类里的名字将遮蔽基类中具有相同名字的任何对象或函数”,
其实还是有方法调用X类的copy的,印象中好象是b.X::copy(&a);不大确定了。
2011-6-19 22:04
0
游客
登录 | 注册 方可回帖
返回
//