第5章 继承与派生的访问规则

前言

继承与派生之间的访问规则到底是怎样的??还在啥啥分不清,今天总算撸出一篇文章总结出来了。

【例5.1】使用继承的案例

//【例5.1】使用继承的案例
#include <iostream>
#include <string>
using namespace std;
class Person{	//声明基类
	public:
		Person(string name1,string id_number,int age1);
		~Person();
		void show();	//在基类中定义了成员函数show()
	private:
		string name;	//姓名
		string id_number;	//身份证号
		int age;	//年龄
};
Person::Person(string name1,string id_number1,int age1)
{
	name=name1;
	id_number=id_number1;
	age=age1;
}
Person::~Person()
{
}
void Person::show()
{
	cout<<"\n 姓名:"<<name;
	cout<<"\n 身份证号:"<<id_number;
	cout<<"\n 年龄:"<<age;
}
class Student:public Person{	//声明公有派生类Student
	public:
		Student(string name1,string id_number1,int age1,int credit1);
		~Student();
		void show();	//在派生类中,重新定义了成员函数show()
	private:
		int credit;		//学分
};
Student::Student(string name1,string id_number1,int age1,int credit1)
	:Person(name1,id_number1,age1)	//定义派生类构造函数时,缀上基类的构造函数
{
	credit=credit1;
}
Student::~Student()
{
}
void Student::show()
{
	Person::show();	//调用基类Person的成员函数show()
	cout<<"\n 学分:"<<credit<<endl;
}
int main()
{
	Student stu1("黎明","110105**********63",19,166);
	stu1.show();	//调用的是派生类中的成员函数show()
	//stu1.Person::show();//不妨加上这条语句,是可以通过对象访问基类的公有成员的,因为是公有继承
	return 0;
}

输出

07e25e0e3aab47a1b181d9a173951c5f.png

公有继承的访问规则
基类成员私有成员公有成员保护成员
内部访问不可访问可访问可访问
对象访问不可访问可访问不可访问

公有派生的对象可以访问基类的公有成员

基类成员在派生类中的访问属性

基类中的成员继承方式基类成员在派生类中的访问属性
私有成员(private)公有继承(public)不可直接访问
私有成员(private)私有继承(private)不可直接访问
私有成员(private)保护继承(protected)不可直接访问
公有成员(public)公有继承(public)公有(public)
公有成员(public)私有继承(private)私有(private)
公有成员(public)保护继承(protected)保护(protected)
保护成员(protected)公有继承(public)保护(protected)
保护成员(protected)私有继承(private)私有(private)
保护成员(protected)保护继承(protected)保护(protected)

 【例5.2】一个私有继承的例子

//【例5.2】一个私有继承的例子
#include <iostream>
#include <string>
using namespace std;
class Person{	//声明基类
	public:
		Person(int age1)
		{	age=age1;	}
		void setage(int age1)
		{	age=age1;	}
		void show();	//在基类中定义成员函数show()
	private:
		int age;		//年龄
};
void Person::show()
{
	cout<<"年龄:"<<age<<endl;
}
class Student:private Person{	//声明私有派生类Student
	public:
		Student(int age1,int credit1);
		void setage_cre(int a1,int c1)
		{
			setage(a1);	//基类的setage()函数在派生类中为私有成员,派生类成员函数可以访问
			credit=c1;	//正确,成员函数setage_cre()可以访问本类的私有成员credit
		}
		void show();	//在派生类中,重新定义了成员函数show()
	private:
		int credit;		//学分
};
Student::Student(int age1,int credit1):Person(age1)	//定义派生类构造函数时,缀上基类的构造函数
{
	credit=credit1;
}
void Student::show()
{
	Person::show();		//调用基类的show()函数显示年龄
	cout<<"学分:"<<credit<<endl;
}
int main()
{
	Student stu1(19,166);
	stu1.setage_cre(20,168);	//正确,setage_cre在类Student为公有成员,派生类对象能访问。
	stu1.show();				//调用的是派生类中的成员函数公有成员show(),派生类对象能访问。
	//stu1.Person::show();		//加上这条语句错误!因为是私有继承,基类所有成员在派生类中为私有,
								//不可通过派生类的对象直接访问.
	return 0;
}

正确输出

0678a694286e436fac37d5ee6529f069.png

加上语句“stu1.Person::show(); ”编译提示

6300e03f156a4f2f807a752603fb01c3.png

 

私有继承的访问规则
基类成员私有成员公有成员保护成员
内部访问不可访问可访问可访问
对象访问不可访问不可访问不可访问

          私有派生的对象不可以访问基类的任何成员 

【例5.3】基类中的保护成员以私有的方式被继承后的访问属性

//【例5.3】基类中的保护成员以私有的方式被继承后的访问属性
#include <iostream>
#include <string>
using namespace std;
class Person{	//声明基类
	public:
		Person(int age1)
		{	age=age1;	}
		void setage(int age1)
		{	age=age1;	}
		void show();	//在基类中定义成员函数show()
	protected:
		int age;		//年龄
};
void Person::show()
{
	cout<<"年龄:"<<age<<endl;
}
class Student:private Person{	//声明私有派生类Student
	public:
		Student(int age1,int credit1);
		void setage_cre(int a1,int c1)
		{
			setage(a1);	//基类的setage()函数在派生类中为私有成员,派生类成员函数可以访问
			//可以改写成:age=a1;	因为age在person中为protected,私有继承过来可以被访问
			credit=c1;	//正确,成员函数setage_cre()可以访问本类的私有成员credit
		}
		void show();	//在派生类中,重新定义了成员函数show()
	protected:
		int credit;		//学分
};
Student::Student(int age1,int credit1):Person(age1)	//定义派生类构造函数时,缀上基类的构造函数
{
	credit=credit1;
}
void Student::show()
{
	cout<<"年龄:"<<age<<endl;	//可以访问基类的protected成员
	cout<<"学分:"<<credit<<endl;
}
class PostGraduate:private Student{	//声明私有派生类PostGraduate
	public:
		PostGraduate(int age1,int credit1,float subsidy1):Student(age1,credit1)
										//定义派生类构造函数时,缀上基类的构造函数
		{
			subsidy=subsidy1;
		}
		void setall(int age1,int credit1,float subsidy1)
		{
			setage_cre(age1,credit1);
			subsidy=subsidy1;
		}
		void show()
		{
			Student::show();	//可以访问
			//cout<<"年龄:"<<age<<endl;		//不可访问,age在person类中是protected,被Student派生后成为private
			cout<<"学分:"<<credit<<endl;	//可访问,credit在Student中为protected
			cout<<"补助:"<<subsidy<<endl;	//可以访问本类私有成员
		}
		private:
			float subsidy;	//补助
};
int main()
{
	PostGraduate PG1(24,29,3000.00);
	PG1.show();
	PG1.setall(24,29,3500.00);
	PG1.show();
	return 0;
}

2aba811c8ea34b89890989e510643461.png

基类中的保护成员以私有的方式被继承后可以在派生类中直接被访问,而私有成员只能间接访问(即通过基类中的公有成员函数访问)。

 

保护继承的访问规则
基类成员私有成员公有成员保护成员
内部访问不可访问可访问可访问
对象访问不可访问不可访问不可访问

          保护派生的对象不能访问基类的任何成员

总结

继承是个啥?到底有啥用?

简单来讲就是子承父类,用csgo里的话讲就是父枪子承!就是提高了代码的利用率,让代码可以重新被利用。

关于父类和子类之间的访问属性傻傻分不清?

  1. 首先,私有成员(private)只要在本类外无论怎样都不能被直接访问!!它们只能在本类中被访问,或者通过本类的公有函数接口来访问。即既不能被本类对象直接访问,也不能在派生类中被直接访问。
  2. 再来说保护成员(protected),保护成员与私有成员的
    1. 相同点是:它们都不能被本类的对象直接访问!!  ,更不能被派生类的对象访问  
    2. 不同点是:保护成员可以在派生类的内部中(无论是什么继承属性,就算是私有继承)被直接访问!!而基类的私有成员被继承(无论是什么继承,就算是公有继承也一样)过来不能在派生类中直接被访问。要想在派生类的内部访问基类的私有成员,只能通过基类的公有或保护成员函数做为接口来访问。
  3. 公有成员(public),公有成员可以被本类的对象直接访问,也可以在派生类的内部被直接访问。也可以被公有派生类的对象直接访问。
  4. 要想通过派生类的对象访问基类中的成员,那只能是公有派生对象访问基类的公有成员。
  5. 要想在派生类的内部直接访问基类中的成员,那只能直接访问基类的公有成员和保护成员

下面的自撸代码例子可以说明我的总结

#include <iostream>
using namespace std;
class Base{
	public:
		int a;
	protected:
		int b;
	private:
		int c;
};
class Derived:private Base{	//私有继承
	void show()
	{
		cout<<a;			//正确   基类的公有成员可以在派生类的内部被直接访问
		cout<<b;			//正确   基类的保护成员可以在派生类的内部被直接访问
//		cout<<c;			//错误   基类的私有成员不能被直接访问
	}
};
class Derived1:protected Base{//保护继承
	void show()
	{
//		cout<<c;			//同样错误   基类的私有成员不能被直接访问
	}
};
class Derived2:public Base{	//公有继承
	void show()
	{
//		cout<<c;			//同样错误  基类的私有成员不能被直接访问
	}
};
int main()
{	
	Base B;
	B.a=0;					//正确,本类对象可以直接访问本类公有成员
//	B.b=0;					//错误,本类对象不可直接访问本类保护成员
//	B.c=0;					//错误,本类对象不可直接访问本类私有成员
	Derived D;
//	D.a=0;					//错误,私有派生类对象不可直接访问基类公有成员
	Derived1 D1;
//	D1.a=0;					//错误,保护派生类对象不可直接访问基类公有成员
	Derived2 D2;
	D2.a=0;					//正确,公有派生类对象可以直接访问基类公有成员
	return 0;
}

如有错误,欢迎广大朋友前来批评指正!! 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值