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

这里主要说的是继承体系中的作用域

class B{

 private:

  int x;

public:

  virtual void mf1()=0;

  virtual void mf2();

  void mf3();

...

};

class D:public B

{

  public:

   virtual void mf1();

  void mf4();

  ...

};

void D::mf4()

{

    ...

  mf2();

  ...

}

函数mf4调用mf2查找名字的顺序是先在mf4函数内,再到D类作用域内,还是没有就到基类B中查找,还是没有的话就到Bnamespace内找,最后到全局作用域。

考虑下面的例子:

class B{

 private:

  int x;

public:

  virtual void mf1()=0;

  virtual void mf1(int);

  virtual void mf2();

  void mf3();

  void mf3(double);

...

};

class D:public B

{

  public:

   virtual void mf1();

  void mf3();

  void mf4();

  ...

};

现在B类的名字mf1mf3D类的mf1mf3掩盖了,所以下面的调用是错误的

int x;

 D d;

d.mf1(x); //error

d.mf3(x);//error

这里的继承采用了继承重载函数。is-apublic继承的基石,base中的东西在派生类中都适用,现在base的东西在派生类中不可见,违反了public继承的准则。

你可以使用using声明达成目的:

class D:public B

{

  public:

   using B::mf1;

   using B::mf3;

   virtual void mf1();

  void mf3();

  void mf4();

  ...

};

现在上面的错误就没有了

现在你只想继承B类中的mf1的无参数函数,怎么办呢?using 声明会导致B类所有的名字在D类中可见,所以using声明在这里就不起作用了。这时候可以用private继承,使用一个简单的转交函数来完成:

class B{

   public:

    virtual void mf1()=0;

   virtual void mf1(int);

   ....

};

class D:private B

{

   public:

   virtual void mf1()  //转交函数,暗自成为inline函数

  {

     B::mf1();            

  }

 ....

};

但是结合template的时候,我们将面临新的问题。这里不给予讨论。

 


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值