多级派生时的访问属性和派生类的构造函数和析构函数

一、多级派生时的访问属性

C-->B-->A

类B称为类A的直接派生类,类C称为类A的间接派生类。类A是类B的直接基类,类A是类C的间接基类。

例:多级派生的访问属性

#include <iostream>
using namespace std;
class A
{
    public:
        int i;
    protected:
        void f1();
        int j;
    private:
        int k;
};
class B:public A//public派生类
{
    public:
        void f2();
    protected:
        void f3();
    private:
        int m;
};
class C:protected B//protected派生类
{
    public:
        void f4();
    private:
        int n;
};

对于上面的这个代码来看,可以得到下表的关系:

各类成员在不同类中的访问属性
类别if1()jkf2()f3()mf4()n
基类A公用被保护的被保护的私有的
基类B公用被保护的被保护的不可访问公用被保护的私有的
基类C被保护的被保护的被保护的不可访问被保护的被保护的的不可访问公用私有的

二、派生类的构造函数和析构函数

构造函数:

主要作用是对数据成员初始化。

在声明派生类时,派生类并没有把基类的构造函数继承过来,因此对继承过来的基类成员初始化的工作要由派生类的构造函数函数承担。

希望达成的目标是:

在执行派生类的构造函数时,使派生类的数据成员和基类的数据成员同时都被初始化。

解决思路:

在执行派生类的构造函数时,调用基类的构造函数。

a、简单的派生类的构造函数

例:定义简单的派生类的构造函数

#include <iostream>
#include <string>
using namespace std;
class Student
{
public:
	Student(int n, string nam, char s)//定义构造函数
	{
		num = n;
		name = nam;
		sex = s;
	}
	~Student() {}
protected:
	int num;
	string name;
	char sex;
};
class Student1 :public Student
{
public:
	Student1(int n, string nam, char s, int a, string ad):Student(n, nam, s)//定义派生类构造函数
	{
		age = a;
		address = ad;
	}

	void show()
	{
		cout << "num=" << num << endl;
		cout << "name=" << name << endl;
		cout << "sex=" << sex << endl;
		cout << "age=" << age << endl;
		cout << "address=" << address << endl;
	}
	~Student1() {}
private:
	int age;
	string address;
};
int main()
{
	Student1 sutd1(10010, "Wang-li", 'f', 19, "115 beijing road,shanghai");
	Student1 stud2(10011, "zhang-fan", 'm', 21, "213 shanghai road,beijing");
	sutd1.show();
		stud2.show();
	return 0;
}

运行结果:

派生类构造函数一般形式为:

派生类构造函数名(总参数表):基类构造函数名(参数表)

{

        派生类中新增数据成员初始化语句

}

:这里不是定义基类构造函数,而是调用基类构造函数,因此这些参数是实参而不是形参。

b、有子对象的派生类构造函数
Student s1;//Student是已声明的类名,s1是Student类的对象

子对象的定义:

这时s1就是类对象中的内嵌对象,称为子对象,即对象中的对象。

例:包含子对象的派生类的构造函数

#include<iostream>
#include<string>
using namespace std;
class Student
{
public:
	Student(int n, string nam)
	{
		num = n;
		name = nam;
	}
	void display()
	{
		cout << "num=" << num << endl;
		cout << "name=" << name << endl;
	}
	~Student(){}
protected:
	int num;
	string name;
};
class Student1 :public Student
{
public:
	Student1(int n, string nam, int n1, string nam1, int a, string ad) :Student(n, nam),monitor(n1,nam1)//monitor(班长)
	{
		age = a;
		addr = ad;
	}
	void show()
	{
		cout << "This student is:" << endl;
		display();
		cout << "age:" << age << endl;
		cout << "address:" << addr << endl;
	}
	void show_monitor()//成员函数输出子对象班长
	{
		cout << endl << "class monitor is:" << endl;
		monitor.display();
	}
	~Student1(){}
private:
	Student monitor;//定义子对象班长
	int age;
	string addr;
};
int main()
{
	Student1 stud1(10010, "wang_li", 10001, "li_jun", 19, "115 beijing road,shanghai");
	stud1.show();
	stud1.show_monitor();
	return 0;
}

运行结果:

派生类构造函数的任务包括3个部分:

1、对基类数据成员的初始化

2、对子类数据成员的初始化

3、对派生类数据成员初始化

调用派生类构造函数的顺序是:
1、调用基类构造函数,对基类数据成员初始化

2、调用子对象构造函数,对子对象数据成员初始化

3、执行派生类构造函数本身,对派生类数据成员初始化

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值