实验九 派生与继承——构造与析构函数
9.1 实验目的
9.2 实验内容
1.理解下面的程序,并运行查看结果,回答程序后面的问题。
#include <iostream>
using namespace std;
class CBase
{
public:
CBase(int a):a(a)
{
}
void print()
{
cout<<"a="<<a<<endl;
}
private:
int a;
};德鲁兹人
class CDerive : public CBase
{
public:
CDerive(int a,int s):CBase(a)
{
b=s;
}
void print()训练日剧情
{
cout<<"b="<<b<<endl;
}
private:
int b;
};
int main()
{
CDerive d(3,4);
d.print();//-----------------------------------------------------①
CBase b(4);
b.print();//-----------------------------------------------------②
return 0;
}
问题一:请指出①与②两处的print函数调用有何区别?
答:①处是调用派生类CDerive的成员函数,在派生类中函数print()与基类中的print()同名,所以它会覆盖基类重中的print()函数,在调用函数时执行派生类的print()函数;而②处是调用CBase类的成员函数。 问题二:修改程序,使程序能输出基类的数据成员a。
答:
1、在①处后面增加代码d.CBase::print();
2、在派生类的print函数中增加语句CBase::print();
2.理解下面的程序,并运行查看结果,回答程序后面的问题。
#include <iostream>
using namespace std;
class CBase
{
public:
CBase(int a)
:a(a)
{
cout<<"base structure"<<endl;
}
~CBase()
{
cout<<"base destructure"<<endl;
}
void print()
{
cout<<"a="<<a<<endl;
}
int a;
};
class CDerive : public CBase
{
public:
CDerive(int a, int b,int c)
:CBase(a),b(b),c(c) //-----------------------------------------------------①
{
cout<<"derive structure"<<endl;
}
~CDerive()
{
cout<<"derive destructure"<<endl;
}
void print()
{
CBase::print();
cout<<"b.a="<<b.a<<endl;
cout<<"c="<<c<<endl;
}
private:
CBase b;
int c;
845主板
};
int main()
{
CDerive d(1,2,3); //-----------------------------------------------------②
d.print();
return 0;
}
问题一:请解释①处的含义?
答:派生类构造函数先调用基类CBase的构造函数,对基类构造函数的数据成员初始化;,再调用子对象b的构造函数,对子类的数据成员初始化;最后执行派生类构造函数本身,对派生类数据成员c初始化。
问题二:②处语句执行完后,d.b.a的值为多少?
答:2
问题三:以上程序的输出结果是什么,说明为什么?
答:
因为派生类构造函数先调用基类CBase的构造函数,将基类构造函数的数据成员a初始化为1;,再调用子对象b的构造函数,将子类的数据成员a初始化为2;再执行派生类构造函数本身,将派生类数据成员c初始化为3;然后执行派生类的析构函数,接着是子类的析构函数,最后是基类的析构函数。
3.以下程序实现的继承关系如下图所示,理解下面的程序,并运行查看结果,回答程序后面的问题。
#include <iostream>
#include <string>
using namespace std;
近代汉语//声明公共基类Person
class Person
{public:
Person(string nam,char s,int a)//构造函数
{name=nam;sex=s;age=a;}
protected: //保护成员
string name;
char sex;
int age;
};
//声明Person的直接派生类Teacher
class Teacher:public Person
{public:
Teacher(string nam,char s,int a, string t):Person(nam,s,a)//构造函数
{title=t; }
protected: //保护成员
string title; };
//声明Person的直接派生类Student
class Student: public Person
{public:
Student(string nam,char s,int a,float sco) //构造函数
:Person(nam,s,a),score(sco){ } //初始化表
protected: //保护成员
float score; //成绩
};
//声明多重继承的派生类Graduate
class Graduate:public Teacher,public Student //Teacher和Student为直接基类
{public:
Graduate(string nam,char s,int a, string t,float sco,float w)//构造函数
:Person(nam,s,a),Teacher(nam,s,a,t),Student(nam,s,a,sco),wage(w){}
//初始化表
void show( ) //输出研究生的有关数据
{cout<<"name:"<<name<<endl;
cout<<"age:"<<age<<endl;
cout<<"sex:"<<sex<<endl;
cout<<"score:"<<score<<endl;
cout<<"title:"<<title<<endl;
cout<<"wages:"<<wage<<endl;
}
private:
float wage; //工资
};
//主函数
int main( )
{Graduate grad1("Wang-li",'f',24,"assistant",89.5,1234.5);
grad1.show( );
return 0;
}
问题一:以上程序错误的原因是什么?请改正。
答:金属的介电常数由于多重继承引起的的二义性,程序在执行函数show( )ctd输出数据成员时无法区别是基类Person的成员,还是Teacher类从基类继承下来的成员,还是Student类从基类继承下来的成员;
改正:
应在Teacher类和Student 类继承基类前加关键字virtual使程序只保留一份成员: