C++名字隐藏对公有继承的影响
来源:互联网 发布:淘宝账号买卖交易平台 编辑:程序博客网 时间:2024/06/08 14:48
在讨论名字隐藏对公有继承的影响前,让我们先来看看什么是名字隐藏,以及它在非继承结构中的影响。
C++中的名字隐藏(Name Hiding)规则简单地理解就是:当一个具有小作用域(inner scope)的对象A和一个作用域包含A(outer scope)的对象B同名时,在A的作用域中,B将不可见。也就是说B完全被A所屏蔽。- double i = 3.1415;
- namespace XY
- {
- bool i = false;
- void f()
- {
- int i = 926;
- cout << i << endl;
- }
- }
当名字隐藏发生的时候,某些情况下使用作用域运算符::是可以访问外层变量的。例如当你需要访问的外层变量处于全局作用域、名字空间、类中时。
- double i = 3.1415;
- namespace XY
- {
- bool i = false;
- void f()
- {
- int i = 926;
- // 输出0
- cout << XY::i << endl;
- // 输出3.1415
- cout << ::i << endl;
- }
- }
- void f()
- {
- int i = 0;
- {
- double i = 3.1415;
- // 无法访问外层的整形变量i
- cout << i << endl;
- }
- }
- void f(int i)
- {}
- void f(int i, int j)
- {}
- namespace XY
- {
- void f()
- {
- f(1); //编译出错,全局f(int i)已被屏蔽
- f(2, 3); //编译出错,全局f(int i, int j)已被屏蔽
- }
- }
从这个例子可以看出,只要函数名相同,所有外层的函数都会被屏蔽,即使类型不同。这点和我们前面在变量上观察到的现象完全一致。
那么,所有的这些会对继承有何影响呢?在一个继承体系中,派生类的作用域是内嵌在基类的作用域之中的。形象一点,就类似于下面的嵌套作用域。- Base
- { //基类作用域开始
- ..
- Derived
- { //派生类作用域开始
- ..
- } //派生类作用域结束
- } //基类作用域结束
- class Base
- {
- public:
- virtual void f();
- virtual void f(int i);
- virtual void f(int i, int j);
- };
- class Derived: public Base
- {
- public:
- virtual void f();
- };
- Derived d;
- d.f();
- d.f(1); //编译出错,基类f(int i)已被屏蔽
- d.f(1, 2); //编译出错,基类f(int i, int j)已被屏蔽
这种情况并非不常见,因为函数的重载和虚函数的重定义都是C++常用特性。问题的解决方法是通过using语句把基类的同名函数的作用域扩展到派生类中来。当然,using的使用必须在派生类的public中,以确保这些接口依然是公有的。
- class Base
- {
- public:
- virtual void f();
- virtual void f(int i);
- virtual void f(int i, int j);
- };
- class Derived: public Base
- {
- public:
- using Base::f;
- virtual void f();
- };
- Derived d;
- d.f();
- d.f(1); //ok
- d.f(1, 2); //ok
小结:
- 尽量避免名字冲突。不要在全局空间使用类似i, j这样的变量名。
- 如果只重定义了基类几个重载函数中的一个,必须使用using语句保证公有派生类继承基类的所有同名接口。
- 另一个警醒是,如果你要在基类中重载一个现有函数时,千万要保证派生类中也有同样的接口!要么重定义,要么使用using。嗯。。在现有代码上增加代码并不是那么简单的。
- C++名字隐藏对公有继承的影响
- C++名字隐藏对公有继承的影响
- c++笔记06---继承,公有继承,继承方式对访控属性的影响,私有继承和保护继承
- C++:公有继承
- 对C++名字隐藏的理解
- C/C++:public公有继承
- C++的公有继承
- 类的公有继承
- 类的公有继承
- c++:私有继承,公有继承,保护继承
- C++:多态公有继承
- 隐藏链接和隐藏文字对seo的影响
- C/C++ 公有继承、保护继承和私有继承的区别
- 继承object对象对python多继承的影响
- 继承与派生:派生类对基类成员的访问控制之公有继承
- 三十七、继承与派生:派生类对基类成员的访问控制之公有继承
- AWS等入华对国内云计算产业和公有云市场格局的影响
- 编译器对C函数的名字修饰
- Web app root system property already set to different value: 'webapp.root'
- Android强制设置横屏或竖屏
- magento常用插件
- VS2010设置编译路径
- 给力的jQuery导航下拉菜单插件
- C++名字隐藏对公有继承的影响
- LinuxC/C++编程基础(18) 视频关键帧长度和宽度的解析(续)
- Web服务的几种实现方法
- Linux的三种内核配置界面
- oracle中exp,imp的使用详解
- linux下打印堆栈方法 锦集
- phpcms常用采集 gbk
- POJ 3667 hotel 和 NYOJ 537 hotel 【线段树之区间合并】
- Hibernate支持两种锁机制