避免遮掩继承而来的名称

C++中类与类之间存在着两种名称遮盖关系,变量遮盖、函数遮盖。其本质都是名字的查找方式导致的,当编译器要找一个名字,它一旦找到一个相符的名字,就不会往下找了,因此遮掩本质上是优先查找那个名字的问题。

    查找名字时,编译器先从子类开始,一旦找到了,就不再继续查找。无论普通函数,虚函数,还是纯虚函数,结果都是输出子类的函数调用。 避免遮掩继承而来的名称是因为,你在使用public继承而又不继承那些重载函数,就是违反base和derive class之间的 is 关系。

如果非要访问父类的方法,用两种方法可以实现

1. 使用using Base::func();声明

2. 定义转交函数

  1. //:采用using声明,使查找范围扩大至父类指定的函数:
  2. class Base
  3. {
  4. public:
  5. void CommonFunction(){cout << "Base::CommonFunction()" << endl;}
  6. void virtual VirtualFunction(){cout << "Base::VirturalFunction()" << endl;}
  7. void virtual VirtualFunction(int x){cout << "Base::VirtualFunction() With Parms" << endl;}
  8. void virtual PureVirtualFunction() = 0;
  9. };
  10. class Derived: public Base
  11. {
  12. public:
  13. using Base::VirtualFunction; // 第一级查找也要包括Base::VirtualFunction
  14. void CommonFunction(){cout << "Derived::CommonFunction()" << endl;}
  15. void virtual VirtualFunction(){cout << "Derived::VirturalFunction()" << endl;}
  16. void virtual PureVirtualFunction(){cout << "Derived::PureVirtualFunction()" << endl;}
  17. };
  18. int main()
  19. {
  20. Derived d;
  21. d.VirtualFunction(3); // 这样没问题了,编译器会把父类作用域里面的函数名VirtualFunciton也纳入第一批查找范围,这样就能发现其实是父类的函数与main中的调用匹配得更好(因为有一个形参),这样会输出Base::VirtualFunction() With Parms
  22. return 0;
  23. }
  1. //:使用转交函数强制指定父类的作用域
  2. class Base
  3. {
  4. public:
  5. void CommonFunction(){cout << "Base::CommonFunction()" << endl;}
  6. void virtual VirtualFunction(){cout << "Base::VirturalFunction()" << endl;}
  7. void virtual VirtualFunction(int x){cout << "Base::VirtualFunction() With Parms" << endl;}
  8. void virtual PureVirtualFunction() = 0;
  9. };
  10. class Derived: public Base
  11. {
  12. public:
  13. using Base::VirtualFunction;
  14. void CommonFunction(){cout << "Derived::CommonFunction()" << endl;}
  15. void virtual VirtualFunction(){cout << "Derived::VirturalFunction()" << endl;}
  16. void virtual PureVirtualFunction(int x){cout << "Derived::PureVirtualFunction()" << endl;}
  17. void virtual VirtualFunction(int x){Base::VirtualFunction(x)};
  18. };
  19. int main()
  20. {
  21. Derived d;
  22. d.VirtualFunction(3); // 输出Base::VirtualFunction() With Parms
  23. return 0;
  24. }

总结: 派生类的名字会遮盖基类的名字

为了让遮盖的名字重见天日,可以用using声明或者转交函数。

来自为知笔记(Wiz)

时间: 2024-10-20 09:55:05

避免遮掩继承而来的名称的相关文章

Effective C++:条款33:避免遮掩继承而来的名称

(一) 下面这段代码: int x; void someFunc() { double x; //local variable std::cin>>x; //read a new value to local x } 这个指涉的是local变量x,而不是global变量x,因为内存作用域会的名称遮掩外围作用域的名称.当编译器处于someFunc的作用域内并遭遇名称x时,他在local作用域内查找是否有什么东西带着这个名称.如果找到就不再找其他作用域.someFunc的x是double类型而gl

《Effective C++》之条款33:避免遮掩继承而来的名称

<Effective C++> 条款33:避免遮掩继承而来的名称 遮掩行为与作用域有关.例子如下: int x;//global变量 void someFun() {     double x;//local 变量     std::cin >> x;//读一个新值赋予local变量x } 这个读取数据的语句指涉的是local变量x,而不是global变量x,因为内层作用域的名称会遮掩外围作用域的名称. 例如: class Base { private:     int x; pu

条款33:避免遮掩继承而来的名称(Avoiding hiding inherited names)

NOTE: 1.derived classes 内的名称会遮掩base classes内的名称.在public继承下从来没有人希望如此. 2.为了让被遮掩的名称再见天日,可使用using 声明方式或转交函数(forwarding functions).

条款33:避免遮掩继承而来的名称

首先看下下面这个例子: class Base{ private: int x; public: virtual void mf1() = 0; virtual void mf2(); void mf3(); ... }; class Derived : public Base{ public: virtual void mf1(); void mf4(); ... }; 这个函数里面还有纯虚函数,虚函数以及非虚函数. 如果这里derived class调用了一个mf2函数的话,那么那么会先在de

Effective C++ 33 避免遮掩继承而来的名称

首先介绍一个原则LSP(Liskov Substitution Principle),如果Class D以Public方式继承Class B,则所有B对象可以派上用场的任何地方,D对象一样可以派上用场. 对于重载和重写,相信大家都已经有所了解.这里讨论一下在public继承的时候,重载函数的问题. 先看下面的例子: 1 class Base 2 { 3 public: 4 virtual void mf1() = 0; 5 virtual void mf1(int); 6 virtual voi

Effective C++ Item 33 避免遮掩继承过来的名称

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie ? 不懂 c++为什么derived classes 内的名称要遮掩 base classes 内的名称. 经验:derived classes 内的名称会遮掩 base classes 内的名称.在 public 继承下从来没有人希望如此. C++ 的名称遮掩规则所做的唯一事情就是: 遮掩名称 derived class 作用域被嵌套在 base class 作用域里 class Bas

C++ 继承体系中的名称覆盖

首先一个简单的样例: int x; int f() { double x; cin >> x; return x; } 在上述代码中.函数f的局部变量x掩盖了全局变量x.这得从 "C++的名字查找机制"说起,首先.在函数f的局部作用域中查找.(甚至是语句块).假设不存在,到上一层的作用域再进行查找,... 该命名空间中查找,最后是全局作用域. 在类的继承体系中,名字覆盖问题也是非常困扰的.此处的"名字"但是是函数名,变量名,typedef, enum都能

条款33:避免隐藏继承而来的名称

• 此例中混合了纯虚函数.虚函数.非虚函数等,只是为了强调隐藏的是继承而来的名字,至于名字代表的是什么并不重要,即使enum.nested class.typedef也不例外. 1 #include <iostream> 2 3 using namespace std; 4 5 class Base 6 { 7 public: 8 virtual void mf1() = 0; 9 virtual void mf1(int); 10 virtual void mf2(); 11 void mf

Effective C++笔记06:继承与面向对象设计

关于OOP 博客地址:http://blog.csdn.net/cv_ronny 转载请注明出处! 1,继承可以是单一继承或多重继承,每一个继承连接可以是public.protected或private,也可以是virtual或non-virtual. 2,成员函数的各个选项:virtual或non-virtual或pure-virtual. 3,成员函数和其他语言特性的交互影响:缺省参数值与virtual函数有什么交互影响?继承如何影响C++的名称查找规则?设计选项有如些?如果class的行为