1. 派生类的作用域

每个类定义自己的作用域,作用域内定义成员,当存在继承关系时,派生类的作用域嵌套在其基类的作用域之内。如果一个名字在派生类的作用域内无法正确解析,则编译器将继续在外层的基类作用域中寻找该名字的定义。

Bulk_quote bulk;
cout << bulk.isbn();

. 首先在Bulk_quote 中查找名字isbn.
. 在Bulk_quote的基类Disc_quote中查找.
. 在Disc_quote的基类Quote中查找.

1.1 在编译时进行名字查找

一个对象、引用或指针的静态类型决定了该对象的哪些成员可见,即使动态类型和静态类型不一致。


namespace oopClassDomainTest
{class Quote {};class Disc_quote : public Quote {public:Disc_quote() {};void discount_policy()   {  }  };class Bulk_quote : public Disc_quote {};void test() {Bulk_quote bulk;Bulk_quote* bulkP = &bulk;//静态类型和动态类型一致Quote* itemP = &bulk;//静态类型和动态类型不一致bulkP->discount_policy(); //okitemP->discount_policy();//error}
}

1.2. 名字冲突与继承

派生类可以重定义基类成员,从而将其隐藏。但可以通过作用域运算符来使用隐藏的成员

 struct Base {Base() : mem(0) { }protected:int mem;};struct Derived : Base {Derived(int i) : mem(i) { } // initializes Derived::mem to i// Base::mem is default initializedint get_mem() { return mem; }  // returns Derived::memint get_base_mem() { return Base::mem; }// . . .protected:int mem;   // hides mem in the base};void test() {Derived d(42);cout << d.get_mem() << endl;       // prints 42cout << d.get_base_mem() << endl;  // prints 0}

1.3 名字查找优先于类型检查

声明在内层作用域的函数并不会重载声明在外层作用域的函数,如果派生类中的函数与基类的某个成员同名,则派生类将在其作用域内隐藏该基类成员,即使形参列表不一致。

namespace oopClassDomainTest3
{struct Base { int memfcn() { return 1; };};struct Derived : Base {int memfcn(int) { return 1; };// hides mem in the base };void test() {Derived d;Base b;b.memfcn();d.memfcn(10);//d.memfcn();//errord.Base::memfcn();//ok }
}

1.4 虚函数和作用域

不论静态类型,调用的是虚函数结果就是虚函数。


class Base {public:virtual int fcn();};class D1 : public Base {public:// hides fcn in the base; this fcn is not virtual// D1 inherits the definition of Base::fcn() int fcn(int);      // parameter list differs from fcn in Basevirtual void f2(); // new virtual function that does not exist in Base};class D2 final : public D1 {public:int fcn(int); // nonvirtual function hides D1::fcn(int)int fcn();    // overrides virtual fcn from Basevoid f2();    // overrides virtual f2 from D1};D1 dobj, * dp = &dobj;dp->fcn(42); // ok: static call to D1::fcn(int)Base bobj;  D1 d1obj; D2 d2obj;Base* bp1 = &bobj, * bp2 = &d1obj, * bp3 = &d2obj;bp1->fcn(); // 虚调用, Base::fcn  bp2->fcn(); // 虚调用, Base::fcn at run timebp3->fcn(); // 虚调用, D2::fcn at run timeD1* d1p = &d1obj; D2* d2p = &d2obj;d1p->f2(); // 虚调用, will call D1::f2() at run timed2p->f2(); // 虚调用, will call D2::f2() at run timeD1* p2 = &d2obj; D2* p3 = &d2obj;p2->fcn(42);  // statically bound, calls D1::fcn(int)p3->fcn(42);  // statically bound, calls D2::fcn(int)D1* dp1 = &d2obj; D2* dp2 = &d2obj;dp1->fcn(10); // static call to D1::fcn(int)dp2->fcn(10); // static call to D2::fcn(int)

1.5 覆盖重载函数

应用场景:基类中可能有多个重载函数,派生类希望覆盖重载函数中的一部分。
解决方法:使用using声明语句指定一个名字而不指定形参列表,一条基类成员函数的using声明语句就可以把该函数所有重载实例添加到派生类作用域。 之后派生类仅需对特定参数的函数定义,无需为其他继承而来的函数定义。

声明在内层作用域的函数并不会重载外层作用域的函数,因此定义派生类的函数也不会重载其基类中的成员。如果同名则外层的名字隐藏。

【引用】

[1] 代码oopTest.h

C++ Primer 5th笔记(chap 15 OOP)继承中的类作用域相关推荐

  1. C++ Primer 5th笔记(chap 15 OOP)抽象基类

    1. 纯虚函数pure virtual 纯虚函数无需定义,通过在函数体的位置书写 =0 就可以将一个虚函数说明为纯虚函数. 其中 =0 只能出现在类内部的虚函数声明语句中. 可以为一个纯虚函数提供定义 ...

  2. C++对象内存布局--③测试多继承中派生类的虚函数在哪一张虚函数表中

    C++对象内存布局--③测试多继承中派生类的虚函数在哪一张虚函数表中 测试2:证明派生类的虚函数的地址跟第一基类的虚函数地址保存在同一张虚函数表中. 派生类有多少个拥有虚函数的基类,派生类对象就有多少 ...

  3. C++ Primer 5th笔记(chap 15 OOP)访问控制与继承

    1. 用户和类的实现者 用户:指类的对象或实例. 类的实现者:包括类的成员. 2. private.public.protect成员 2.1派生类可以访问公有public成员,而不能访问私有priva ...

  4. C++ Primer 5th笔记(chap 15 OOP)继承概念

    1. 派生类可以访问其基类中的公有成员和受保护的成员. 一个派生类对象包含多个组成部分:含有派生类自定义的对象,继承自基类的对象. eg. 一个单继承的例子. //定义基类 class Quote{p ...

  5. C++ Primer 5th笔记(chap 15 OOP)构造函数和拷贝控制

    1. 虚析构函数 基类通常应该定义一个虚析构函数. class Quote {public:// virtual destructor needed if a base pointer pointin ...

  6. C++ Primer 5th笔记(chap 15 OOP)概述

    面向对象程序设计的核心思想: 数据抽象:将类的接口与实现分类. 继承:可以定义相似的类型并对其相似关系建模. 动态绑定:我们能用同一段代码分别处理不同的对象.相同函数,根据动态绑定的对象实质进行区别. ...

  7. C++ Primer 5th笔记(chap 18 大型程序工具)虚继承

    1. 问题 派生类可以多次继承同一个类. 派生类可以通过它的两个直接基类分别继承同一个间接基类, 也可以直接继承某个基类, 然后通过另一个基类再一次间接继承该类.如果某个类在派生过程中出现了多次, 则 ...

  8. C++ Primer 5th笔记(chap 18 大型程序工具) 多重继承与虚继承

    1. 多重继承 (multiple inheritance) 一个类从多个直接基类派生 eg. class Bear : public ZooAnimal {class Panda : public ...

  9. C++ Primer 5th笔记(chap 19 特殊工具与技术)使用 RTTI

    1. RTTI用处 当想为具有继承关系的类实现相等运算符时.对于两个对象来说,如果他们的类型相同并且对应的数据成员取值相同,则我们说这两个类是相等的. class Base {friend bool ...

最新文章

  1. 人群密度估计--Learning a perspective-embedded deconvolution network for crowd counting
  2. tf.name_scope() 和 tf.variable_scope() 的用法和玄机
  3. LoadRunner录制回放常见问题及解决方案
  4. WCF服务的REST / SOAP端点
  5. 由浅到浅入门批量渲染(一)
  6. python解决https私密连接警告信息
  7. android jar 反射,android 第三方jar库 反射得到自己的资源ID
  8. 告诉你银行在年底为存储做的小动作
  9. java数据横转竖_关于竖表转横表的问题
  10. 等级保护三级安全建设
  11. python分析国家统计局数据网站人口结构、出生率、死亡率等基本情况
  12. 牛客网——Java刷题篇
  13. 计算机dns无法修改,Win7系统怎么改DNS地址 修改电脑DNS地址教程具体介绍
  14. REDIS04_主从复制概述及搭建、反客为主、薪火相传、原理、哨兵模式、集群搭建
  15. 精力充沛才能走得更远更从容
  16. SAP中采购收货冲销和退货适用情形简析
  17. python微信发送消息过于频繁_微信发送信息频率上限?
  18. 白色恋人--18首扣人心弦的经典情歌
  19. 分布式存储HBASE原理学习
  20. 如何源码编译zeppelin

热门文章

  1. html视频海报代码,如何在网站头部添加视频海报?添加视频海报的方法(代码示例)...
  2. php执行只读文件,php实现以只读方式打开文件的方法
  3. 各色“独特的”数据中心安置法,藏太深了!
  4. java was datasource_使用Spring Boot配置Druid时dataSource无法被autowired
  5. Py之cython:python库之cython的简介、安装、使用方法之详细攻略
  6. DL之DNN优化技术:利用Batch Normalization(简介、入门、使用)优化方法提高DNN模型的性能
  7. JAVA_OA(六):SpringMVC登陆实例
  8. ubuntu160.4+anaconda3 +tensorflow1.140 +keras2.2.5安装
  9. 功能测试话题分享-0323
  10. Net.Core导入EXCel文件里的数据