C++ 继承体系中的名称覆盖
来源:互联网 发布:js lambda表达式 编辑:程序博客网 时间:2024/06/15 19:37
首先一个简单的例子:
int x;int f(){ double x; cin >> x; return x;}
在上述代码中,函数f的局部变量x掩盖了全局变量x。这得从 “C++的名字查找机制“说起,首先,在函数f的局部作用域中查找,(甚至是语句块),如果不存在,到上一层的作用域再进行查找,... 该命名空间中查找,最后是全局作用域。
在类的继承体系中,名字覆盖问题也是很困扰的。此处的"名字"可是是函数名,变量名,typedef, enum都可以,此处以函数名为例。
值得注意的是,Derived的作用域是嵌套在Base作用域中的。
对于下面的代码:
class Base{public: //对于C++类中定义的任何类型的函数,名字覆盖的规则都是一样的。 virtual void func1(int x){cout << "func1(int) in Base ..." << endl;} void func2(){cout << "func2() in Base ..." << endl;} virtual void func3() = 0;};class Derived : public Base{public: void func1() {cout << "func1() in Derived..." << endl;} void func2(int x) {cout << "func2(int) in Derived..." << endl;} void func3() {cout << "func3() in Derived..." << endl;} void func3(int ) {cout << "func3() in Derived..." << endl;}};int main(){ Derived d; d.func1(3); //调用失败。编译器在Derived的作用域中找到了该函数名字,但是发现调用不匹配,不能通过编译 d.func2(); return 0;}
Base基类中定义了函数func1 与 func2,在派生类中重写了函数func1,并定义了该函数的重载版本。
对于main函数内的调用,见注释解析。
编译器在面对函数调用时,首先是在作用域范围内查找该函数名(由内之外), 如果找到了该函数名之后,编译器便停止查找,开始检查形参与实参的匹配是否合法, 如果不合法,不能通过编译。
如果要在上述代码中调用 基类中的版本 func1(int),那么就需要让编译器在看到该函数调用时,第一时间看到base中的该函数名字,因此,using声明解决了这个难题,在Derived类定义体内部使用using base::func1声明,也就是让Base中的func1函数名字在 ”编译器查找Derived“作用域是可见 。
using的位置放在哪里???!!!
很简单的道理,public继承 意味 ” is a “的关系,那么在Base class中的 public的名称在Derived中也应该是public。
但是,如果你并不想继承 Base中的所有的函数,只想继承一部分,那么 这就无关于函数名字的问题了, 既然如此,public继承就不应该被使用!!
因此,我会告诉你,使用private继承或许有这样的福利。
假设Derived以private形式继承Base,而Derived中只想要继承Base中的某个特定的函数版本,那么using已经不管用了,你需要的是其他的技术。
例如下面的简单例子:
class Base{public: void func1(){cout << "func1 in Base" << endl;}};class Derived : public Base{public: void func1() { Base::func1(); //转交函数,相当于将func1 in Base 转交给func1 in Derived }};
最后,在C++的名字查找中,为了避免Base的函数名覆盖,使用using 声明或者转交函数来完成。
- C++ 继承体系中的名称覆盖
- 继承中的覆盖
- 继承中的函数覆盖
- 继承中的函数名称遮掩
- Java继承中的方法覆盖
- Java中的继承、重载、覆盖
- JAVA中的继承和覆盖
- 继承中的隐藏和覆盖
- C++_继承名字覆盖
- c++ 继承中的覆盖,隐藏,虚拟继承
- C++ 继承中的覆盖,隐藏,虚拟继承
- java中的异常的继承体系
- (转)C++继承中的重载、覆盖和隐藏
- C++继承中的重载、覆盖和隐藏
- C++继承中的重载,覆盖和隐藏
- C++继承中的重载、覆盖和隐藏
- 剖析Delphi中的多态、继承,覆盖
- java继承中的“缺陷”:“覆盖”私有方法
- Java自带优秀工具2
- 闭包—Swift学习笔记(十)
- 购买DigtalOcean VPS 以及 连接Linux
- android直接访问电脑里面的mysql
- sql server2008R2 连接access
- C++ 继承体系中的名称覆盖
- VC++程序员如何做好界面
- vs2010使用备忘
- 计算机系统函数(过程)调用堆栈分析
- C/C++中容器vector使用方法<第一弹>
- MFC MDI程序的退出菜单突然不能退出了
- java中的网络编程详解 TCP 和UDP
- 互联网金融“众筹”试水姑苏
- 三大工厂模式