重载、覆盖、隐藏

C++中类成员函数的重载、覆盖、隐藏

重载

重载指的是多个同名函数,这些函数的参数列表都不同(可能是参数个数不同,或许是参数类型不同)

成员函数重载特征:

(1)同一个作用域范围(成员函数就是在同一个类中)

(2)成员函数名相同

(3)参数列表不同 (参数个数不同、参数类型不同或两个皆不同)

(4)通过参数区分函数,说明多个函数肯定不是一个地址空间

(5)返回值类型可不同(只有返回值不同是不能重载的)重载函数不能通过返回值来区别重载函数

重载的好处:

(1)不用因为参数类型或参数个数不同,而写多个函数。

(2)可以是一些函数,特定的运算符发具有多种功能(最常用的就是,运算符重载)

举例:赋值运算符重载

#include<iostream>
using namespace std;

class Person
{
public:
	Person(int age)//有参构造
	{
		m_age = new int(age);//初始化成员变量
	}
	~Person()//析构函数
	{
		if (m_age!= NULL)
		{
			delete m_age;
			m_age = NULL;
		}
	}
	//赋值运算符的重载
	Person& operator=(Person &p)//返回自身需要引用
	{
		//编译器提供是浅拷贝

		//m_age = p.age;

		//应该先判断是否有属性在堆区,如果有先释放干净
		if (m_age != NULL)
		{
			delete m_age;
			m_age = NULL;
		}
		//深拷贝
		m_age = new int(*p.m_age);
		//*m_age = *p.m_age;

		//返回自身
		return *this;
	}

	int* m_age;
};

void test()
{
	Person P(18);

	Person P1(20);

	Person P2(30);

	P2 = P1 = P;//赋值操作
	cout << "P的年龄为:" << *P.m_age << endl;
	cout << "P1的年龄为:" << *P1.m_age << endl;
	cout << "P2的年龄为:" << *P2.m_age << endl;
	
}
int main()
{

	test();


	system("pause");
	return 0;
}

运行结果

 运行结果显示:如果我们使用普通的(=)运算符,实现的是浅拷贝,在类中有指针的情况下,是无法直接用一个类对象给另一个类对象赋值的,就需要我们进行深拷贝,当我们重载了(=)后,可进行深拷贝。

覆盖

覆盖是指派生类方法覆盖从基类继承过来的方法(覆盖也叫重写),当基类中的方法被覆盖后,可用super关键字调用

覆盖特征:

(1)不同的范围(分别位于派生类与基类)

(2)成员函数名相同,且参数相同,返回类型相同

(3)基类函数必须有virtual关键字(虚函数)

覆盖条件:    借助博客文章参考:点击打开链接

1、“三同一不低” 子类和父类的方法名称,参数列表,返回类型必须完全相同,而且子类方法的访问修饰符的权限不能比父类低。
2、子类方法不能抛出比父类方法更多的异常。即子类方法所抛出的异常必须和父类方法所抛出的异常一致,或者是其子类,或者什么也不抛出;
3、被覆盖的方法不能是final类型的。因为final修饰的方法是无法覆盖的。
4、被覆盖的方法不能为private。否则在其子类中只是新定义了一个方法,并没有对其进行覆盖。
5、被覆盖的方法不能为static。所以如果父类中的方法为静态的,而子类中的方法不是静态的,但是两个方法除了这一点外其他都满足覆盖条件,那么会发生编译错误。反之亦然。即使父类和子类中的方法都是静态的,并且满足覆盖条件,但是仍然不会发生覆盖,因为静态方法是在编译的时候把静态方法和类的引用类型进行匹配。

隐藏

隐藏:派生类中重新定义基类同名函数的方法,称为对基类函数的覆盖或改写,覆盖后基类同名函数在派生类中被隐藏。

隐藏特征:当基类中有多个重载函数并且派生类中有同名函数,则基类中的所有同名函数被隐藏,若想调用基类函数仍然要显示使用基类名

#include<iostream>
using namespace std;
class Animal		//定义基类
{
public:
	//定义speak函数
	void speak() {
		cout << "animal language" << endl;
	}
};
class Cat :public Animal		//定义派生类,且继承
{
public:
	//定义speak函数
	void speak() {
		cout << "cat language  miao miao" << endl;
	}
};

int main()
{
	Cat cat;//定义派生类对象
	cat.speak();//通过派生类调用speak函数
	cat.Animal::speak();//调用基类同名函数
	system("pause");
	return 0;
}

运行结果:

 通过结果可知,第一次调用的时候并不是调用的基类中的函数,而是派生类中的函数,而调用

基类中的同名函数,需要显示的使用基类名。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值