c++隐藏

今天才知道c++继承里面的隐藏特性,真是孤陋寡闻了。

#include <iostream>
using namespace std;
class A
{
public:
     void print()
    {cout<<"A"<<endl;}
};

class B:public A
{
public:
    void print(int a)
    {cout<<"B"<<endl;}
};
int main()
{
    B b = B();
    b.print(); // 报错,error: no matching function for call to 'B::print()' 
    // note: candidate: void B::print(int) note: candidate expects 1 argument, 0 provided
    // 有了print(int a) 把print()隐藏了
    B* b=new B();
    b->print(); // 报错
}

隐藏的不光是成员函数,还可以是成员变量。

★在子类的内部或者外部(通过子类成员)访问该成员,全部访问的子类同名成员。

★在子类的内部或者外部(通过子类成员)访问该同名的成员函数,调用的是子类的成员函数。

这里“隐藏”是指派生类的函数屏蔽了与其同名的基类函数,规则如下:
(1)如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual关键字,基类的函数将被隐藏(注意别与重载混淆)。
(2)如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual关键字。此时,基类的函数被隐藏(注意别与覆盖混淆)。

原因

  • 因为你继承一个基类的时候,很多时候你是不知道这个基类里面具体有哪些成员函数的(比如说你继承的基类来自于某个类库,或者大型项目中,可能因为分工不同,你需要继承的基类是别的开发人员做的),如果基类成员函数没有被隐藏,就会被当成函数重载来处理。但是基类的重载函数,很可能会出现我们意料之外的处理结果。举个例子。假如你写了一个函数A,读入的参数是一个浮点型的数据,返回值为读入参数的2倍。这时候碰巧基类里面有个同名成员函数A,读入的参数是一个整型的数据,但返回值为读入参数的3倍。这时候,你调用派生类的A函数,如果用户输入一个整型,按照你原本的设计,本应该是要把这个参数强制转换为浮点型返回它的2倍,但是因为基类成员函数没有被隐藏,所以就会当成函数重载处理,返回它的3倍。这样就会与你原先的设计冲突了。

  • 不是隐藏,而是命名空间查找顺序的问题.
    C++中,遇到一个函数调用,需要根据名字来确定调用的是哪一个函数,这时候如果派生类定义了该函数,就不会在基类的名字空间中去找.


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章