避免遮掩而来的继承名称

序言

避免继承而来的名称其实是和作用域有关联,常见的是局部作用域会屏蔽全局作用域。

int x;   //全局
void function()
{
double  x = 0.0; //局部  不论是int 还是double
std::cin>>x;
]

C++ 名称这样规则,就是尽量去遮掩名称,至于类型是否相同或者不同,不显得那么重要。当我们实现子类去继承基类时,我们可以理解为子类作用域嵌套在父类的作用域。C++查找各作用域的顺序以下例子示例,

class TestFindNameClass
{
public:
    TestFindNameClass();
    virtual ~TestFindNameClass(){}

    virtual void f1() = 0;
    virtual void f2();
    void f3();

private:
    int m_x;
};

class TestFindNameClassChild : public TestFindNameClass
{
public:
    virtual void f1();
    void f4();
};

#include "testfindnameclass.h"
#include <QDebug>
TestFindNameClass::TestFindNameClass()
{

}

void TestFindNameClass::f2()
{
    qDebug() << __FUNCTION__;
}

void TestFindNameClassChild::f1()
{
    qDebug() << __FUNCTION__;
}

void TestFindNameClassChild::f4()
{
    qDebug() << __FUNCTION__;
    f2();
}

子类嵌入父类作用域图。
在这里插入图片描述
当我们调用f4中的f2时,它会去查找各作用域,看看有没有名为f2的声明式。

  1. 先是所在的f4覆盖的作用域。如果没有,便去外围作用域。
  2. class TestFindNameClassChild作用域下去找,如果还没有,便去嵌套的父类去找。
  3. class TestFindNameClass作用域去找。
  4. 内涵的 TestFindNameClass的作用域(namespace去找)。
  5. 最后去全局的作用域下去找。
当我们在mian.cpp调用时
 TestFindNameClassChild child;
   child.f4();

结果如下

TestFindNameClassChild::f4
TestFindNameClass::f2

那么问题来了,当基类中有重载函数时,那么我们如何避免名称遮掩去父类中调用我们所要的函数呢。

class TestFindNameClass
{
public:
    TestFindNameClass();
    virtual ~TestFindNameClass(){}

    virtual void f1() = 0;
    virtual void f1(int);
    virtual void f2();
    void f3();
    void f3(double);
private:
    int m_x;
};

class TestFindNameClassChild : public TestFindNameClass
{
public:
    virtual void f1();
    void f3();
    void f4();
};
#include "testfindnameclass.h"
#include <QDebug>
TestFindNameClass::TestFindNameClass()
{

}

void TestFindNameClass::f1(int para)
{
    qDebug() << __FUNCTION__ << " para = " << para;
}

void TestFindNameClass::f2()
{
    qDebug() << __FUNCTION__;
}

void TestFindNameClass::f3()
{
    qDebug() << __FUNCTION__;
}

void TestFindNameClass::f3(double para)
{
    qDebug() << __FUNCTION__ << " para = " << para;
}

void TestFindNameClassChild::f1()
{
    qDebug() << __FUNCTION__;
}

void TestFindNameClassChild::f3()
{
    qDebug() << __FUNCTION__;
}

void TestFindNameClassChild::f4()
{
    qDebug() << __FUNCTION__;
    f2();
}

main.cpp 调用如下

TestFindNameClassChild child;
   int x = 1;
   double para = 3.0;
   child.f1();
   child.f4();
   child.f1(x);
   child.f2();
   child.f3();
   child.f3(para);

结果:
在这里插入图片描述
结果如下会发现父类的f1 与 f3未被子类继承,与其说是没被继承,不如说是名称被遮掩了,导致名称没有没找到。

解决方法
using 基类::方法名 会使同名继承而来的函数都可见(在对应访问属性中添加)

class TestFindNameClassChild : public TestFindNameClass
{
public:
    using TestFindNameClass::f1;
    using TestFindNameClass::f3;
    virtual void f1();
    void f3();
    void f4();
};

结果如下:
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

道阻且长,行则降至

无聊,打赏求刺激而已

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值