继承中的类的作用域

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

  派生类的作用域位于基类的作用域之内这一事实可能有点出人意料,毕竟在我们的程序文本中派生类和基类的定义是相互分离开来的。不过也恰恰因为类的作用域有这种继承嵌套的关系,所以派生类才能像使用自己成员一样使用基类的成员。例如,当我们编写下面的额代码时:

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

名字isbn的解析将按照下述过程所示:

  • 因为我们是通过Bulk_quote的对象调用isbn的,所以首先在Bulk_quote中查找,这一步没有找到isbn。
  • 因为Bulk_quote是Disc_quote的派生类,所以接下来在Disc_quote中查找,仍然找不到。
  • 因为Disc_quote是Quote的派生类,所以接着查找Quote;此时找到了名字isbn,所以我们使用的isbn最终被解析为Quote中的isbn。

在编译器时进行名字查找

  一个对象、引用或指针的静态类型决定了该对象的哪些成员是可见的。即使静态类型和动态类型可能不一致(当使用基类的引用或指针时会发生这种情况),但是我们能使用哪些成员仍然由静态类型决定的。举个例子,我们可以给Disc_quote添加一个新成员,该成员返回一个存有最小(或最大)数量及折扣价格的pair:

class Disc_quote : public Quote
{
public:
    pair<size_t, double> discount_policy() count
    { return {quantity, discount}; }
};

int main()
{
    Bulk_quote bulk;
    Bulk_quote bulkP = &bulk; //静态类型与动态类型一致
    Quote *itemP = &bulk;     //静态类型和动态类型不一致
    bulkP->discount_policy(); //正确:bulkP的类型是Bulk_quote*
    itemP->discount_policy(); //错误:itemP的类型是Quote*
}

尽管bulk中确实含有一个名为discount_policy的成员,但是该成员对于itemP却是不可见的。itemP的类型是Quote的指针,意味着对discount_policy的搜索将从Quote开始。显然Quote不包含名为discount_policy的成员,所以我们无法通过Quote的对象、引用或指针调用discount_policy。

名字冲突和继承

  和其它作用域一样,派生类也能重新定义在其直接基类或间接基类中的名字,此时定义在内层的作用域(即派生类)的名字将隐藏定义在外层作用域(即基类)的名字:

class Base
{
public:
    Base() : mem(0) {}
protected:
    int mem;
};

class Derived : Base
{
public:
    Derived(int i) : mem(i) {}
    int get_mem() {return mem;}
protected:
    int mem;
};

int main()
{
    Derived d(42);
    cout << d.get_mem() << endl;
}

通过作用域解析符来使用被隐藏的成员

  我们可以通过作用域解析符来使用一个被隐藏的基类成员:

class Derived : Base
{
public:
    int get_base_mem() {return Base::mem;}
};

 

转载于:https://www.cnblogs.com/bootblack/p/11379293.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值