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(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;
}

当子类函数与父类拥有同名的成员函数,子类会隐藏父类中的同名成员函数,加作用域可以访问到父类中同名函数

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值