而来的继承名称"/>
避免遮掩而来的继承名称
序言
避免继承而来的名称其实是和作用域有关联,常见的是局部作用域会屏蔽全局作用域。
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的声明式。
- 先是所在的f4覆盖的作用域。如果没有,便去外围作用域。
- class TestFindNameClassChild作用域下去找,如果还没有,便去嵌套的父类去找。
- class TestFindNameClass作用域去找。
- 内涵的 TestFindNameClass的作用域(namespace去找)。
- 最后去全局的作用域下去找。
当我们在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();
};
结果如下:
更多推荐
避免遮掩而来的继承名称
发布评论