当子类与父类拥有同名的成员函数,子类会隐藏父类中所有版本的同名成员函数,如果想访问父类中被隐藏的同名成员函数,需要加父类的作用域
#include <cstdlib>
#include <string>
#include<iostream>
using namespace std;
class Base{
public:
Base()
{
m_a = 100;
}
void func()//成员函数,不是构造函数
{
cout<<"Base-func()调用"<<endl;
}
// void func(int a)
// {
// cout<<"Base - func(int a)调用"<<endl;
// }
public:
int m_a;
};
class Son:public Base{
public:
// Son()
// {
// m_a = 200;
// }
void func(int a)
{
cout<<"Son - func()调用"<<endl;
}
public:
int m_a;
};
void test01()
{
Son s;
Base b;
cout<<"Son下的m_a "<<s.m_a<<endl;//子类对象可以直接访问到子类的同名成员 200
//访问父类同名成员的方法有两个
//1、父类直接访问
cout<<"Base下的m_a "<<b.m_a<<endl; // 100
//2、子类对象加作用可以访问到父类同名成员
cout<<"Base下的m_a "<<s.Base::m_a<<endl; //100
s.func();//报错,no matching function for call to 'Son::func()'
//有了func(int a)把func()隐藏起来了
Son *S = new Son();
S->func();//报错,原因同上
}
int main()
{
test01();
return 0;
}
这里“隐藏”是指派生类的函数屏蔽了与其同名的基类函数,规则如下:
(1)如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual关键字,基类的函数将被隐藏(注意别与重载混淆)。
(2)如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual关键字。此时,基类的函数被隐藏(注意别与覆盖混淆)。
————————————————
版权声明:本文为CSDN博主「爆米花好美啊」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u013010889/article/details/89706961
#include <cstdlib>
#include <string>
#include<iostream>
using namespace std;
class Base{
public:
Base()
{
m_a = 100;
}
void func(int a)
{
cout<<"Base - func(int a)调用"<<endl;
}
public:
int m_a;
};
class Son:public Base{
public:
Son()
{
m_a = 200;
}
void func()
{
cout<<"Son - func()调用"<<endl;
}
public:
int m_a;
};
void test01()
{
Son s;
Base b;
cout<<"Son下的m_a "<<s.m_a<<endl;//子类对象可以直接访问到子类的同名成员 200
//访问父类同名成员的方法有两个
//1、父类直接访问
cout<<"Base下的m_a "<<b.m_a<<endl; // 100
//2、子类对象加作用可以访问到父类同名成员
cout<<"Base下的m_a "<<s.Base::m_a<<endl; //100
s.func(10);//被隐藏
}
int main()
{
test01();
return 0;
}
原因
因为你继承一个基类的时候,很多时候你是不知道这个基类里面具体有哪些成员函数的(比如说你继承的基类来自于某个类库,或者大型项目中,可能因为分工不同,你需要继承的基类是别的开发人员做的),如果基类成员函数没有被隐藏,就会被当成函数重载来处理。但是基类的重载函数,很可能会出现我们意料之外的处理结果。举个例子。假如你写了一个函数A,读入的参数是一个浮点型的数据,返回值为读入参数的2倍。这时候碰巧基类里面有个同名成员函数A,读入的参数是一个整型的数据,但返回值为读入参数的3倍。这时候,你调用派生类的A函数,如果用户输入一个整型,按照你原本的设计,本应该是要把这个参数强制转换为浮点型返回它的2倍,但是因为基类成员函数没有被隐藏,所以就会当成函数重载处理,返回它的3倍。这样就会与你原先的设计冲突了。
不是隐藏,而是命名空间查找顺序的问题.
C++中,遇到一个函数调用,需要根据名字来确定调用的是哪一个函数,这时候如果派生类(子类)定义了该函数,就不会在基类的名字空间中去找.
解决方法,加作用域
#include <cstdlib>
#include <string>
#include<iostream>
using namespace std;
class Base{
public:
Base()
{
m_a = 100;
}
void func()//成员函数,不是构造函数
{
cout<<"Base-func()调用"<<endl;
}
void func(int a)
{
cout<<"Base - func(int a)调用"<<endl;
}
public:
int m_a;
};
class Son:public Base{
public:
Son()
{
m_a = 200;
}
void func()
{
cout<<"Son - func()调用"<<endl;
}
public:
int m_a;
};
void test01()
{
Son s;
Base b;
cout<<"Son下的m_a "<<s.m_a<<endl;//子类对象可以直接访问到子类的同名成员 200
//访问父类同名成员的方法有两个
//1、父类直接访问
cout<<"Base下的m_a "<<b.m_a<<endl; // 100
//2、子类对象加作用可以访问到父类同名成员
cout<<"Base下的m_a "<<s.Base::m_a<<endl; //100
s.Base::func(10);
s.Base::func();
}
int main()
{
test01();
return 0;
}
当子类函数与父类拥有同名的成员函数,子类会隐藏父类中的同名成员函数,加作用域可以访问到父类中同名函数