C++程序员大挑战之三----让人目瞪口呆的存储权限

marrco2005 2007-06-12 09:06:57
前言:本帖只关心理论,而不会考虑其是否有实际意义。

假设有如下的类体系结构:

class A
{
public:
void Display(){ printf("\nDisplay()\n");};

protected:
void Protected_Display() { printf("\n Protected_Display()\n"); };
};

class B : protected A // .............注意,是 protected 派生
{
public:
using A::Display;
using A::Protected_Display;
};

int main()
{
B b;
b.Display(); //.................................(1)
b.A::Display(); //.................................(2)
b.Protected_Display(); //.................................(3)
b.A::Protected_Display();//.................................(4)

}

问题1:
在上述的(1)(2)(3)(4)四个调用中,有那些调用会造成编译错误?

问题2:
如果编译器编译的结果与您预先设想的不符,您是否认为这是编译器的一个BUG?
...全文
6564 72 打赏 收藏 转发到动态 举报
写回复
用AI写文章
72 条回复
切换为时间正序
请发表友善的回复…
发表回复
sjjf 2007-07-20
  • 打赏
  • 举报
回复
呵呵,标题党
xiewenbo 2007-07-15
  • 打赏
  • 举报
回复
using 声明已经把继承来的成员函数的访问权限改为public 故在外部可以访问(so 1,3 are ok )
I think 2 also is ok,it is public,so it can be saw outside,while the 4 is protected so it is an error.
If the compiler is not the same with me ,maybe it is a bug of the compiler.
xiewenbo 2007-07-15
  • 打赏
  • 举报
回复
hgfdhbgfdbhgdf
fu320212253 2007-07-14
  • 打赏
  • 举报
回复
只是看看 没学过 只学C#
jinwei1984 2007-07-14
  • 打赏
  • 举报
回复
mark!
Juchiyufei 2007-07-14
  • 打赏
  • 举报
回复
MARK 看看
蜜_Lumia 2007-07-14
  • 打赏
  • 举报
回复
我才刚开始学,也看不出什么来,但我查了一下,那里面的错误还瞒多的。
jik4444 2007-07-13
  • 打赏
  • 举报
回复
c++ builder6.0 能编译通过 vc++6.0 不能编译通过
是什么原因啊 是不是跟编译器还是有关系的呀?
概念上我同意marrco2005(高手前传)
cs0711BF826 2007-07-13
  • 打赏
  • 举报
回复
说实在话,用了C++这么久,就没有好好研究过几种继承的区别,平时用public和private就足够了。这个题目还是有必要继续讨论下去的,不管它有多少实际应用意义,但是通过讨论,我们还是可以有益于对C++更深的了解。
Insider 2007-07-13
  • 打赏
  • 举报
回复
mark,学习
web2me 2007-07-12
  • 打赏
  • 举报
回复
www.jtcj.cn
liuwei200000 2007-07-12
  • 打赏
  • 举报
回复
MARK 看看
tmhlcwp 2007-07-12
  • 打赏
  • 举报
回复
MARK 看看
liyongmsn 2007-07-12
  • 打赏
  • 举报
回复
长见识了
rularys 2007-06-21
  • 打赏
  • 举报
回复
public 误写为 pupbic了
rularys 2007-06-21
  • 打赏
  • 举报
回复
既然是protected继承,那么就不能用B的对象访问这个基类,所以(2)和(4)不能通过编译吧.如果是pupbic继承,那么(2)的访问是合法的,因为B的基类A以及A::Display()都是开放的,但是(4)就不行了,因为A::Protected_Display()是保护的.如果编译器不是这样,我也不能解释.
petty108 2007-06-20
  • 打赏
  • 举报
回复
学习了
没学明白
dazhuaye 2007-06-18
  • 打赏
  • 举报
回复
学习ing
marrco2005 2007-06-15
  • 打赏
  • 举报
回复
我觉得Vitin(卫亭) 以及 iambic() 的回帖应该就是这个问题的答案了,下面附上他们的回帖:




Vitin(卫亭) ( ) 信誉:100 Blog 加为好友 2007-6-13 19:28:15 得分: 0
class B
{
......
using A::Protected_Display;
......
};

等价于

class B
{
......
void Protected_Display() { A::Proteccted_Display(); }
......
};

================================================================================


iambic() ( ) 信誉:100 Blog 加为好友 2007-6-13 2:34:06 得分: 0

看了下上面的回贴,好像没人解释(1)和(2)实质上的区别。我试着解释下吧,不对或者不清楚的地方大家纠正补充。

b.Display(); //.................................(1)
b.A::Display(); //.................................(2)

C++里面,编译器面对一个函数的调用有三件事要做:
1、名字查找
2、重栽决议
3、权限检查

名字查找这一步会逐级查找一个名字,找到一个匹配的名字立刻结束。

在(1)这个例子中,编译器会先在B的scope中查找Display,很快它找到了一个Display,这个Display已经被using声明导入到B的scope当中,并且权限设置为public。所以这个Display最终会被允许调用。

而在(2)的例子中,b.A::Display显式指定了名字查找的scope为A,而A的scope之中的Display是被禁止的。

在A、B各自的scope中,Display具有不同的访问权限。不同scope的名字查找产生了不同的结果,我觉得这是两者的区别所在。

================================================================================
marrco2005 2007-06-15
  • 打赏
  • 举报
回复
goldcool() ( ) 信誉:95 Blog 加为好友 2007-6-13 1:01:27 得分: 0

根据<<C++ PRIMER>>中,第804页中所说的:"派生类只能将继承得到的成员恢复到原来的访问级别,该访问级别不能比基类中原来的指定的级别更严格或更不严格".
所以,我觉得3和4是错误的.
======================================================================
《C++ PRIMER(第三版)》第804页是这样写的。不过我想这一版写的比较早,所以和现在的C++标准有些不符的地方。
我查了一下C++标准,上面是这样写的:

15 The alias created by the using-declaration has the usual accessibility for a member-declaration. [Example:
( ISO/IEC ISO/IEC 14882:2003(E) 7 Declarations 7.3.3 The using declaration )

class A {
private:
void f(char);
public:
void f(int);
protected:
void g();
};
class B : public A {
using A::f; // error: A::f(char) is inaccessible
public:
using A::g; // B::g is a public synonym for A::g
};
—end example]

所以,我觉得可以这样讲:
"派生类能将继承得到的成员恢复到原来的访问级别,该访问级别可以比基类中原来的指定的级别更严格或更不严格"
加载更多回复(52)

15,440

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 非技术区
社区管理员
  • 非技术区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧