知识大全 避免覆蓋通过继承得到的名字

Posted 名字

篇首语:拳不离手,曲不离口。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 避免覆蓋通过继承得到的名字相关的知识,希望对你有一定的参考价值。

莎士比亚有一个关于名字的说法 What s in a name? 他问道 A rose by any other name would smell as sweet (语出《罗密欧与朱丽叶》第二幕第二场 朱生豪先生译为 姓名本来是没有意义的 我们叫做玫瑰的这一种花 要是换了个名字 他的香味还是同样的芬芳

   梁实秋先生译为 姓算什么?我们所谓有玫瑰 换个名字 还是一样的香 ——译者注) 莎翁也写过 he that filches from me my good name makes me poor indeed (语出《奥塞罗》第三幕第三场 朱生豪先生译为 可是谁偷去了我的名誉 那么他虽然并不因此而富足 我却因为失去它而成为赤贫了 梁实秋先生译为 但是他若夺去我的名誉 于他不见有利 对我却是一件损失哩 ——译者注) 好吧 在 C++ 中 我们该用哪种态度对待通过继承得到的名字呢?   事情的实质与继承没什么关系 它与作用域有关 我们都知道它在代码中是这样的      int x; // global variable    void someFunc()      double x; // local variable   std::cin >> x; // read a new value for local x      读入 x 的语句指涉 local 变量 x 而不是 global 变量 x 因为内层作用域的名字覆蓋( 遮蔽 )外层作用域的名字 我们可以像这样形象地表示作用域的状况      当编译器在 someFunc 的作用域中遇到名字 x 时 他们巡视 local 作用域看看是否有什么东西叫这个名字 因为那里有 它们就不再检查其它作用域 在此例中 someFunc 的 x 类型为 double 而 global x 类型为 int 但这不要紧 C++ 的 name hiding 规则仅仅是覆蓋那个名字 而相对应的名字的类型是否相同是无关紧要的 在此例中 一个名为 x 的 double 覆蓋了一个名为 x 的 int   加入 inheritance 以后 我们知道当我们在一个 derived class member function 内指涉位于 base class 内的一件东西(例如 一个 member function 一个 typedef 或者一个 data member)时 编译器能够找到我们指涉的东西是因为 derived classes 继承到声明于 base classes 中的东西 实际中的运作方法是将 derived class 的作用域嵌套在 base class 作用域之中 例如   class Base   private:    int x;      public:    virtual void mf () = ;    virtual void mf ();    void mf ();       ;      class Derived: public Base   public:    virtual void mf ();    void mf ();       ;

  本例中包含的既有 public 名字也有 private 名字 既有 data members 也有 member functions member functions 既有 pure virtual 的 也有 simple (impure) virtual 的 还有 non virtual 的 那是为了强调我们谈论的事情是关于名字的 例子中还可以包括其它类型的名字 例如 enums nested classes 和 typedefs 在这里的讨论中唯一重要的事情是 它们是名字 与它们是什么东西的名字毫不相关 这个示例中使用了 single inheritance 但是一旦你理解了在 single inheritance 下会发生什么 C++ 在 multiple inheritance 下的行为就很容易预见了   假设 mf 在 derived class 中被实现 其中一部分 如下      void Derived::mf ()            mf ();        

  当编译器看到这里对名字 mf 的使用 它就必须断定它指涉什么 它通过搜索名为 mf 的某物的定义的作用域来做这件事 首先它在 local 作用域中搜索(也就是 mf 的作用域) 但是它没有找到被称为 mf 的任何东西的声明 然后它搜索它的包含作用域 也就是 class Derived 的作用域 它依然没有找到叫做 mf 的任何东西 所以它上移到它的上一层包含作用域 也就是 base class 的作用域 在那里它找到了名为 mf 的东西 所以搜索停止 如果在 Base 中没有 mf 搜索还会继续 首先是包含 Base 的 namespace(s)(如果有的话) 最后是 global 作用域   我刚刚描述的过程虽然是正确的 但它还不是一个关于 C++ 中名字如何被找到的完整的描述 无论如何 我们的目的不是为了充分了解关于写一个编译器时的名字搜索问题 而是为了充分了解如何避免令人吃惊的意外 而对于这个任务 我们已经有了大量的信息   再次考虑前面的示例 而且这一次我们 overload mf 和 mf 并且为 Derived 增加一个 mf 的版本 (Derived 对 mf ——一个通过继承得到的 non virtual function ——的重载 使得这个设计立即变得可疑 但是出于对 inheritance 之下名字可见性问题的关心 我们就装作没看见 )     class Base   private:    int x;     public:    virtual void mf () = ;    virtual void mf (int);      virtual void mf ();       void mf ();    void mf (double);       ;      class Derived: public Base   public:    virtual void mf ();    void mf ();    void mf ();       ;

  以上代码导致的行为会使每一个第一次遇到它的 C++ 程序员吃惊 基于作用域的名字覆蓋规则(scope based name hiding rule)不会有什么变化 所以 base class 中的所有名为 mf 和 mf 的函数被 derived class 中的名为 mf 和 mf 的函数覆蓋 从名字搜索的观点看 Base::mf 和 Base::mf 不再被 Derived 继承!      Derived d;   int x;         d mf (); // fine calls Derived::mf   d mf (x); // error! Derived::mf hides Base::mf   d mf (); // fine calls Base::mf      d mf (); // fine calls Derived::mf   d mf (x); // error! Derived::mf hides Base::mf   就像你看到的 即使 base 和 derived classes 中的函数具有不同的参数类型 它也同样适用 而且不管函数是 virtual 还是 non virtual 它也同样适用 与 在本文的开始处 函数 someFunc 中的 double x 覆蓋了 global 作用域中的 int x 的道理相同 这里 Derived 中的函数 mf 覆蓋了具有不同类型的名为 mf 的一个 Base 函数   这一行为背后的根本原因是为了防止 当你在一个 library 或者 application framework 中创建一个新的 derived class 时 偶然地发生从遥远的 base classes 继承 overloads 的情况 不幸的是 一般情况下你是需要继承这些 overloads 的 实际上 如果你使用了 public inheritance 而又没有继承这些 overloads 你就违反了 base 和 derived classes 之间是 is a 关系 这一 public inheritance 的基本原则 在这种情况下 你几乎总是要绕过 C++ 对 通过继承得到的名字 的缺省的覆蓋机制   你可以用 using declarations 做到这一点      class Base   private:    int x;      public:    virtual void mf () = ;    virtual void mf (int);       virtual void mf ();       void mf ();    void mf (double);       ;     class Derived: public Base   public:    using Base::mf ; // make all things in Base named mf and mf    using Base::mf ; // visible (and public) in Derived s scope      virtual void mf ();    void mf ();    void mf ();       ;

cha138/Article/program/ASP/201311/21840

相关参考

知识大全 通过继承扩展接口

  利用继承技术可方便地为一个接口添加新的方法声明也可以将几个接口合并成一个新接口在这两种情况下最终得到的都是一个新接口如下例所示    //:HorrorShowjava  //Extendinga

知识大全 多线程从线程继承

    为创建一个线程最简单的方法就是从Thread类继承这个类包含了创建和运行线程所需的一切东西Thread最重要的方法是run()但为了使用run()必须对其进行过载或者覆蓋使其能充分按自己的吩咐

知识大全 房子是父母的名字,等父母去世之后自动继承吗

房子是父母的名字,等父母去世之后自动继承吗《继承法》第二条继承从被继承人死亡时开始。《物权法》第二十九条 因继承或者受遗赠取得物权的,自继承或者受遗赠开始时发生效力。最高人民法院关于贯彻执行《中华人民

知识大全 避免起破财的名字

猪年到了,小编给大家介绍一些避免破财的名字,快来一起看看吧。1.第一个避免破财的方法,名字的笔画是三十九画,原因是个人脑洞太大,想象力太丰富,虽然本身的能力比较强,但是总是幻想通过一些别的手段来获得更

下列关于常生可否得到补偿的说法何者正确

下列关于常生可否得到补偿的说法何者正确?A、应当得到补偿,分配数额应当小于法定继承人B、应当得到补偿,分配数额可以等于或大于法定继承人的继承份额C、如常生明知法定继承人分割遗产而未提出请求,即丧失遗产

我国公民的财产继承权主要是通过法定继承方式实现的

我国公民的财产继承权主要是通过法定继承方式实现的。_____答案:错误解析:依据我国《继承法》的规定,公民继承权的实现主要依赖于两种方式:法定继承和遗嘱继承。

自然失业可以通过__得到解决

自然失业可以通过_____得到解决。A、经济手段B、社会保障手段C、法律手段D、不能解决答案:D解析:在充分就业状态下,难以避免的失业即是自然失业。自然失业是由非经济原因引起的,不能通过经济手段解决。

王某去世后,留有下列一些财产,其中能作为遗产继承的是

王某去世后,留有下列一些财产,其中能作为遗产继承的是_____。A、贪污受贿所得的10万元B、捡到别人的银行卡一张C、购买福利彩票得到的8万元D、放高利贷得到的5万元利息答案:C解析:《继承法》第3条

知识大全 通过继承Thread创建多线程

通过继承Thread创建多线程  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!一个进程中可以包含一个

从人类文明发展的垂直继承关系来看,有了图书,后人就无需要事事躬亲,渐渐从头做起。通过阅读图书,就可以极其有效地继承了前人

从人类文明发展的垂直继承关系来看,有了图书,后人就无需要事事躬亲,渐渐从头做起。通过阅读图书,就可以极其有效地继承了前人的知识、经验、认识和技能,从已有的认识和成果出发,去创造新的认识和成果。因为图书