Effective C++ 之条款33避免遮掩继承而来的名称

编程入门 行业动态 更新时间:2024-10-07 04:33:25

Effective C++ 之条款33避免遮掩继承<a href=https://www.elefans.com/category/jswz/34/1766077.html style=而来的名称"/>

Effective C++ 之条款33避免遮掩继承而来的名称

    名称的遮掩可以分为变量的遮掩和函数的遮掩两类,本质上都是通过名字的查找方式导致的,当编译器查找一个名字的时候,他一旦找到一个相符的名字,他就不会再找下去了,所以核心是看它从哪个作用域先找,因为查找是分作用域的。

//例1:普通变量遮掩
int i = 3;  //global 变量int main()
{int i = 4;  //local变量cout << i << endl; // 输出4
}

上面的代码可以看作是普通变量的遮掩,在cout中输出i的时候,它首先在局部变量范围内查找,找到之后就不往上面找了。

对于名称的遮掩,主要重点在于名称,而不在于变量是什么类型(double 可以遮掩 int)。

下面我们再看看类成员变量的遮掩

class Base
{
public:int x;Base(int _x) :x(_x) {};
};class Derived :public Base
{public:int x;Derived(int _x) :Base(_x), x(_x + 1) {};int getbase_x() { return Base::x; };
};int main()
{Derived d(3);std::cout << d.x<< std::endl;  //输出结果为4std::cout << d.getbase_x() << std::endl;  //输出结果为3return 0;
}

    虽然基类与派生类当中都有成员变量x,但是他们是相互隔离的。我再派生类中调用d.x,编译器会优先在派生类中查找。这也就是基类与派生类之间的成员变量的遮掩。

   与变量遮掩类似,函数名的查找也是先从子类独有的作用域开始查找的,一旦找到,就不再继续找下去了。这里无论是普通函数,虚函数,还是纯虚函数,结果都是输出子类的函数调用。

  但有一种情况要注意:

  

class Base
{
public:int x;Base(int _x) :x(_x) {};void CommonFunction() { std::cout << "Base::CommonFunction()" << std::endl; }void virtual VirtualFunction() { std::cout << "Base::VirturalFunction()" << std::endl; }void virtual VirtualFunction(int x) { std::cout << "Base::VirtualFunction() With Parms" << std::endl; }void virtual PureVirtualFunction() = 0;};class Derived :public Base
{public:int x;Derived(int _x) :Base(_x), x(_x + 1) {};void CommonFunction() { std::cout << "Derived::CommonFunction()" << std::endl; }void virtual VirtualFunction() { std::cout << "Derived::VirturalFunction()" << std::endl; }void virtual VirtualFunction() { std::cout << "Derived::VirturalFunction()" << std::endl; }void virtual PureVirtualFunction() { std::cout << "Derived::PureVirtualFunction()" << std::endl; }};int main()
{Derived d(3);d.VirtualFunction(3);  //这里会报错,因为派生类同名成员函数没有参数列表,他是不会去基类成员 函数中寻找的。//d.CommonFunction();	//d.PureVirtualFunction();return 0;
}

     很多人都会认为输出的是Base::VirtualFunction() With Parms,实际上这段代码却是编译不过的。因为编译器在查找名字时,并没有“为重载而走的很远”,C++的确是支持重载的,编译器在发现函数重载时,会去寻找相同函数名中最为匹配的一个函数(从形参个数,形参类型两个方面考虑,与返回值没有关系),如果大家的匹配程度都差不多,那么编译器会报歧义的错。

但以上法则成立的条件是这些函数位于相同的作用域中,而这里是不同的域!编译器先查找子类独有的域,一旦发现了完全相同的函数名,它就已经不再往父类中找了!在核查函数参数时,发现了没有带整型形参,所以直接报编译错了。

如果去掉子类的VirualFunction(),那么才会找到父类的VirtualFunction(int)。

提醒一下,千万不要被前面的Virtual关键字所误导,你可以试一个普通函数,结果是一样的,只要子类中有同名函数,不管形参是什么,编译器都不会再往父类作用域里面找了。

 

 

 

更多推荐

Effective C++ 之条款33避免遮掩继承而来的名称

本文发布于:2024-02-14 01:07:32,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1761427.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:而来   条款   名称   Effective

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!