子类可变更从父类继承的成员的作用域违背了面向对象的封装性

foosine 2009-05-09 12:19:36
一直以为为了保证封装性,父类成员的作用域是不可以被子类所扩展的。今天写测试代码时,发现以下的代码竟然可以编译通过,吓出一身冷汗。哪位高人评评看

#include <iostream>

class BaseClass
{
public:
int x;
protected:
int y;
};

class SubClass:public BaseClass
{
public :
BaseClass::y; // 在此将父类的保护成员变成了公共成员
protected:
BaseClass::x;
};

int main()
{
SubClass obj;
obj.y = 10;
printf("%d",obj.y);
return 0;
}
...全文
232 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
光宇广贞 2009-05-09
  • 打赏
  • 举报
回复
而在VC# 2008中,子类恢复基类保护成员的做法会引发编译时异常的。
光宇广贞 2009-05-09
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 CARL_SEN 的回复:]
我在vc6.0和vs2008中测试居然都成功,惊!C++ Primer上说在private和protected继承下,派生类可以恢复继承成员的访问级别,但不能使访问级别比基类中原有的更严格或更宽松。这里尽然可以放宽基类成员的访问级别,茫然!期待~~
[/Quote]

还有这等事儿?
不过楼主的可是公有继承。

私有和保护继承的方式下,我认为吧,就算可以放宽访问级别的话,我觉得可以视为派生类新定义的成员,与基类的同名成员无关,而且,外部可访问的,也只是这个类的这个成员罢了。
CARL_SEN 2009-05-09
  • 打赏
  • 举报
回复
我在vc6.0和vs2008中测试居然都成功,惊!C++ Primer上说在private和protected继承下,派生类可以恢复继承成员的访问级别,但不能使访问级别比基类中原有的更严格或更宽松。这里尽然可以放宽基类成员的访问级别,茫然!期待~~
光宇广贞 2009-05-09
  • 打赏
  • 举报
回复
public :
BaseClass::y; // 在此将父类的保护成员变成了公共成员

这是不可能的……
foosine 2009-05-09
  • 打赏
  • 举报
回复
有请高手!
foosine 2009-05-09
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 hikaliv 的回复:]
而在VC# 2008中,子类恢复基类保护成员的做法会引发编译时异常的。
[/Quote]

我不知道4楼的有没有亲自动手试过,我自己在vs2008和linux下的gcc测试都是可以正确运行的,就算用了私有继承,结果仍然是一样。
pathuang68 2009-05-09
  • 打赏
  • 举报
回复
请朋友们用别的编译器试试,看看是个什么结果。前几天将RHEL AS4删了,还没重装:)
foosine 2009-05-09
  • 打赏
  • 举报
回复
请看看这篇文章,即使是基类中私有成员,也有办法可以在子类对其进行访问:
http://blog.csdn.net/pathuang68/archive/2009/04/20/4096088.aspx
见其中的红色字体提醒部分。
----------------------------------------------------------------------------
这是从内存上直接访问,同样的,只要愿意,我们还可以访问到当前线程栈空间的任意一个地址的值。
但这样的访问方式和C++的语义本身已经没什么关系了呀
pathuang68 2009-05-09
  • 打赏
  • 举报
回复
谢谢LZ的发现,先收藏了再说。
pathuang68 2009-05-09
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 pengzhixi 的回复:]
你在public下用using Base::x再试下能编译过去么
[/Quote]
如果7L兄弟说的是下面这样的话:

class SubClass : public BaseClass
{
public :
using BaseClass::y;
protected:
BaseClass::x;
};

编译和运行也是OK的。
pathuang68 2009-05-09
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 hikaliv 的回复:]
引用 2 楼 CARL_SEN 的回复:
我在vc6.0和vs2008中测试居然都成功,惊!C++ Primer上说在private和protected继承下,派生类可以恢复继承成员的访问级别,但不能使访问级别比基类中原有的更严格或更宽松。这里尽然可以放宽基类成员的访问级别,茫然!期待~~


还有这等事儿?
不过楼主的可是公有继承。

私有和保护继承的方式下,我认为吧,就算可以放宽访问级别的话,我觉得可以视为派生类新定义的成员,与基类的同名…
[/Quote]
如果是这样,那就更奇怪了。也就是说SubClass中会有两个y,一个是从BaseClass继承来的,一个是SubClass自己的一个与基类同名的y,那如果在SubClass中引用y的时候,岂不会产生二义性?
pengzhixi 2009-05-09
  • 打赏
  • 举报
回复
你在public下用using Base::x再试下能编译过去么
pathuang68 2009-05-09
  • 打赏
  • 举报
回复
5L观点更正:
经过反复试验,楼主的发现是正确的!
很有意思!

下面的观点维持原来的判断:
请看看这篇文章,即使是基类中私有成员,也有办法可以在子类对其进行访问:
http://blog.csdn.net/pathuang68/archive/2009/04/20/4096088.aspx
见其中的红色字体提醒部分。
pathuang68 2009-05-09
  • 打赏
  • 举报
回复

class SubClass:public BaseClass
{
public :
BaseClass::y; // 在此将父类的保护成员变成了公共成员
protected:
BaseClass::x;
};

上述代码中的BaseClass::y; 并没有将父类的保护成员编程公共成员。请看:

从上图中可以看到y在SubClass中仍然是protected的。

请看看这篇文章,即使是基类中私有成员,也有办法可以在子类对其进行访问:
http://blog.csdn.net/pathuang68/archive/2009/04/20/4096088.aspx
见其中的红色字体提醒部分。
所以其实也没有什么啦。

65,210

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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