C++/子类介绍/访问等级/成员函数同名问题

本文介绍了面向对象编程中的继承概念,包括父亲类和子类的关系,以及三种继承方式(public、protected、private)。示例展示了如何通过public继承创建子类,并讨论了访问权限的影响。此外,还讲解了函数遮蔽问题,即子类同名函数会覆盖父类的同名函数,并提供了如何在子类中调用父类同名函数的方法。
摘要由CSDN通过智能技术生成

概念

类之间的有一种层次关系,有父亲类,孩子类.
父亲类:基类,超类
孩子类:子类,派生类
继承:有父亲类,有孩子类,构成了层次关系

(面向对象有三个核心:继承,封装,多态)

继承

这种继承,简单说就是需要先定义一个父类,父类中定义一些公用的成员变量,成员函数,我们通过继承父类来构建新的类,也就是子类;

所以,写代码时,只需要写和子类相关的一些内容即可.

示例

“Human.h”

#ifndef  __HUMAN__
#define  __HUMAN__

#include <iostream>
using namespace std;

class Human
{
public:
	Human();
	Human(int);
	
private:
	int m_Age;
	char m_Name[100];

};

#endif // !__HUMAN__

“Human.cpp”

#include "Human.h"

Human::Human()
{
	cout << "执行了构造函数Human::Human()" <<endl;
}

Human::Human(int)
{
	cout << "执行了构造函数Human::Human(int)" << endl;
}

“Man.h”

#ifndef  __MEN__
#define  __MEN__

#include <iostream>
#include "Human.h"

using namespace std;

class Men : public Human  //表示Men是Human的子类
{
public:
	Men();

};
#endif

“Man.cpp”

#include "Men.h"

Men::Men()
{
	cout << "执行了构造函数Men::Men()" << endl;
}

“Main”

#include "Men.h"
#include  <iostream>

int main()
{
	Men men;		//执行了构造函数Human::Human()
							//执行了构造函数Men::Men()
	//当定义子类对象时,是要调用父类和子类的构造函数,而且,父类的构造函数的函数体先执行,子类构造函数的函数体后执行

	return 0;
}

在这里插入图片描述
整个程序的运行结果是先执行父类构造函数的函数体,在执行子类构造函数的函数体;

访问等级

三种访问权限

public: 可以被任意实体访问
protected: 只允许本类或者子类成员函数访问
private: 只允许本类成员函数访问

继承方式

从刚才的示例中可以看到,通过public方式继承父类,当然,也可以使用这三种方式.

class Men : public Human
class Men : protected Human
class Men : private Human

子类所能得到的权限:
在这里插入图片描述
示例中加入一些测试代码,可以测试一下这些权限,以下是举例:
说明:子类继承方式为public

//"Human.h"
public:
	int m_Age;
	char m_Name[100];

	void funcpub() {};

protected:
	int m_pro;
	void funcpro() {};

private:
	int m_priv;
	void funcpriv() {};
int main()
{
	Men men;		
	men.m_Age;  //允许,父类public,任意实体访问
	men.m_pro;  //不允许,protected只允许本类或者子类的成员函数访问\
				   这里是main函数,显然不行;  可以再Men中的成员函数中访问
	men.m_priv;  //不允许, 访问权限不够,只允许父类的成员函数*访问
	
	return 0;
}

如果子类继承方式为protected,那么父类public 也要变成protected(子类想要访问只能在成员函数中访问)(详细看表)

函数遮蔽问题

父类函数

//这里是父类 Human
public:
	void sameFunc();
	void sameFunc(int);

子类函数

//这里是子类 men
public:
	void sameFunc(int);

main

//调用测试
	Men men;//实例一个子类
	men.sameFunc(123);  //这里调用了子类的sameFunc(int)函数,而不是父类的
	men.sameFunc();     //报错,无法调用父类中的不带参同名函数

范例中可以看出,当子类和父类存在同名成员函数时,通过子类,无法调用父类中的同名函数,因为子类中的函数遮蔽掉了父类中的同名函数.
解决这个问题的方法就是:
(1)在子类成员函数中调用,但是要注意,在子类成员函数中调用是,要加上"父类名::成员函数名(…)的方式来调用"
例:子类构造中

Man::Man()
{
	Human::sameFunc();     //可以调用
	Human::sameFunc(123);  //带参也可以调用
	//两个函数都成功调用了父类的同名函数,Human::很关键
}

(2)如果Men是以public方式继承自Human父类,在main函数中,用"子类对象名.父类名::成员函数名(…)"的方式也能调用父类同名成员函数.

	Men men;//实例一个子类
	men.Human::sameFunc(123);   //这里调用的是父类带参同名成员函数
	men.Human::sameFunc();  	//不带参,同样是父类

(3)可以通过using声明

public:
 using Human::samenamefunc; //只能指定函数名,不能带形参列表,并且父类必须是public或\
 								protected(只能在子类成员函数中使用)

当然就算声明了using,在调用过程中,调用了跟子类同参同名函数,还是会优先调用子类,父类依旧会被覆盖.
想继续调用父类,还是要加Human::sameFunc() 父类名::同名函数(…)

总结
虽然子类可以调用父类的同名函数,但是实际意义可能并不大,如果子类覆盖了父类,那一般说明子类对象并不想调用父类,否则完全可以写成不同名的.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值