zoukankan      html  css  js  c++  java
  • 第十章 继承与派生练习题

    网易云音乐链接 : 点我听歌.

    练习:
    一、继承与派生——公有

    实例:

    #include<iostream.h>
    class A			//A类
    {
    private :
    	int a;
    public :
    	void inita(int n)	//初始化A类的成员变量
    	{
    		a=n;
    	}
    	int geta()			//访问获取A类的值
    	{
    		return a;
    	}
    
    };
    class B:public A //B类继承A类
    {
    private:
    		int b;
    public:
    	void initb(int m)   //初始化B类的成员变量
    	{
    		b=m;
    	}
    	int getb()			//访问获取B类的值跟A类的成员变量相乘并返回结果
    	{
    		return b*geta();
    	}
    };
    
    void main()
    {
    	int s;				//存取后续的值
    	B ob;				//创建一个B类的对象ob
    	//oa.inita(5);		
    	ob.A::inita(5);		//初始化a的值(派生类拥有基类的成员特性)
    	ob.initb(8);		//初始化内部b的值
    	s=ob.getb();		//调用函数并返回值给 s
    	cout<<s<<endl;		//打印输出
    }
    

    运行结果:

    在这里插入图片描述
    二、继承与派生–私有

    实例:

    #include<iostream.h>
    class A					//A类
    {
    private :
    	int a;
    public :
    	void inita(int n)	//初始化成员变量
    	{
    		a=n;
    	}
    	int geta()			//返回成员变量的值
    	{
    		return a;
    	}
    
    };
    class B:private A		//B继承A(私有继承)---私有特性
    {
    private:
    		int b;
    public:
    	void initb(int m,int n)   //由于私有继承,需要公有函数来访问并初始化基类
    	{
    		b=m;
    		inita(n);				//初始化A类的成员变量
    	}
    	int getb()					//获取成员变量与基类成员变量的积
    	{
    		return b*geta();
    	}
    };
    
    void main()
    {
    	int s;						//用于存放返回值
    	B ob;						//创建一个对象ob
    	ob.initb(8,5);				//初始化成员变量
    	s=ob.getb();				//返回乘积
    	cout<<s<<endl;				//打印
    }
    

    运行结果:

    在这里插入图片描述

    三、子类的构造函数、析构函数
    定义人类 学生类 老师类

    实例:

    #include<iostream.h>
    
    class person						//创建person类
    {
    public:
    	int age;						//年龄
    	char *name;						//名字指针
    public:
    	void eat();						
    	void run();						//功能函数(人能干什么)
    	person(int x,char *s);			//构造函数---初始化成员变量
    	~person();						//析构函数(与构造函数成对存在)
    };
    void person::eat()					//人类“吃”函数
    {
    	cout<<"人类吃饭"<<endl;
    }
    void person::run()					//人类“运动”函数
    {
    	cout<<"人类运动"<<endl;
    }
    person::person(int x,char *s)		//构造函数初始化
    {
    	age=x;
    	name=s;
    	cout<<"人类构造函数"<<endl;
    }
    person::~person()					//析构函数
    {
    	cout<<"人类析构函数"<<endl;
    }
    class student:public person			//学生student类公有继承person
    {
    public:
    	char *sno;						//学生标志(可以填学号)
    public:
    	void study();					//学生功能函数
    	student(int x,char *s,char *s1):person(x,s)//子类的构造函数---参数列表(给基类成员变量初始化)
    	{
    		sno=s1;
    	cout<<"学生类构造函数"<<endl;
    	}
    	~student();						//子类析构函数
    };
    
    void student::study()				//功能函数
    {
    	cout<<"学生学习"<<endl;
    }
    student::~student()					//
    {
    	cout<<"学生类析构函数"<<endl;
    }
    	
    class teacher:public person			//老师teacher类公有继承person类
    {
    public:
    	char *tno;						//老师标志位(工号)
    public:
    	void teach();					//老师功能函数
    	teacher(int x,char *s,char *s1):person(x,s)//子类的构造函数
    	{
    		tno=s1;
    	cout<<"教师类构造函数"<<endl;
    	}
    	~teacher();
    };
    void teacher::teach()
    {
    	cout<<"教师教书"<<endl;
    }
    
    teacher::~teacher()
    {
    	cout<<"教师类析构函数"<<endl;
    }
    
    
    void main()
    {
    	person p1(20,"xiaoming");				//基类对象	
    	student s1(20,"xiaoli","2018110110");	//student类对象
    	teacher t1(20,"fubw","2540");			//teacher类对象
    	//p1.age=20;
    	//p1.name="小明";
    	cout<<p1.age<<endl;						//打印p1基类对象的年龄
    	cout<<p1.name<<endl;					//打印p1基类对象的名字
    	
    	p1.eat();								
    	p1.run();								//打印p1基类对象的功能
    	
    	cout<<s1.age<<endl;						//打印s1学生类对象的年龄
    	cout<<s1.name<<endl;					//打印s1学生类对象的名字
    	cout<<s1.sno<<endl;						//打印s1学生类对象的学号
    	s1.person::eat();						
    	s1.eat();
    	s1.person::run();
    	s1.study();								//打印s1学生类对象的功能
    
    
    	t1.teach();								//打印t1老师类对象的功能
    	cout<<t1.age<<endl;						//打印t1老师类对象的年龄
    	cout<<t1.name<<endl;					//打印t1老师类对象的名字
    	cout<<t1.tno<<endl;						//打印t1老师类对象的工号
    
    }
    

    运行结果:

    在这里插入图片描述

    四、多重继承

    存在问题的实例:

    #include <iostream>
    using namespace std;
        
    class Person							//Person类
    {
    public:
    	void sleep()
    	{cout << "sleep" << endl;}
        void eat() 
    	{cout << "eat" << endl;}
    };
        
    class Author : public Person            //Author继承自Person
    {
    public:
    	void writeBook() 
    	{cout << "write Book" << endl;}
    };
        
    class Programmer : public Person      //Programmer继承自Person 
    {
    public:
    	void writeCode() 
    	{cout << "write Code" << endl;}
    };
        
    class Programmer_Author : public Programmer, public Author    //多重继承
    {
    };
        
    int main()
    {
    	Programmer_Author pa;
    	pa.writeBook();   //调用基类Author的方法
    	pa.writeCode();   //调用基类Programmer的方法
        pa.eat();         //编译错误,eat()定义不明确 在Author 和Programmer继承时添加virtual
        pa.sleep();       //编译错误,sleep()定义不明确
    	//pa.Author::eat();//指定到底是哪个基类的方法
        
        return 0;
    }
    
    

    报错:

    在这里插入图片描述

    修改:

    在继承Person类的两个类前面加上 virtual
    class Author : virtual public Person
    class Programmer : virtual public Person

    #include <iostream>
    using namespace std;
        
    class Person							//Person类
    {
    public:
    	void sleep()
    	{cout << "sleep" << endl;}
        void eat() 
    	{cout << "eat" << endl;}
    };
        
    class Author : virtual public Person            //Author继承自Person
    {
    public:
    	void writeBook() 
    	{cout << "write Book" << endl;}
    };
        
    class Programmer : virtual public Person      //Programmer继承自Person 
    {
    public:
    	void writeCode() 
    	{cout << "write Code" << endl;}
    };
        
    class Programmer_Author : public Programmer, public Author    //多重继承
    {
    };
        
    int main()
    {
    	Programmer_Author pa;
    	pa.writeBook();   //调用基类Author的方法
    	pa.writeCode();   //调用基类Programmer的方法
        pa.eat();         //编译错误,eat()定义不明确 在Author 和Programmer继承时添加virtual
        pa.sleep();       //编译错误,sleep()定义不明确
    	//pa.Author::eat();//指定到底是哪个基类的方法
        
        return 0;
    }
    

    运行结果:

    在这里插入图片描述

    五、虚基类
    虚基类:解决继承中 间接多次继承同一个类 所出现的二义性问题

    主要看看构造函数的加载先后顺序
    父类-----子类------孙类

    实例:

    #include<iostream.h>
    class p				
    {
    public :
    	char *name;
    public :
    	p()
    	{
    		name="xiaoming";
    		cout<<"p类的构造函数 "<<name<<endl;
    	};
    };
    class s:virtual public p
    {
    	public :
    	s()
    	{
    		cout<<"s类的构造函数 "<<name<<endl;	
    	}
    
    };
    
    class w :virtual public p
    {
    	public :
    	w()
    	{
    		cout<<"w类的构造函数 "<<name<<endl;	
    	}
    };
    class sw: public s, public w
    {
    	public :
    	sw()
    	{
    		cout<<"sw类的构造函数 "<<name<<endl;	
    	}
    };
    void main()
    {
    	p p1;
    	s s1;
    	w w1;
    	sw sw1;
    }
    

    运行结果:

    在这里插入图片描述

    作业:

    一、选择题:
    1、定义派生类时,若不使用关键字显式地规定采用体积继承方式,则默认方式是______。
    A.私有继承 B.非私有继承 C.保护继承 D.公有继承
    2、在一个派生类的成员函数中,试图调用其基类的成员函数“void f();”,但无法通过编译。这说明______。
    A. f()是基类的私有成员 B.f()是基类的保护成员
    C.派生类的继承方式是私有 D.派生类的继承方式为保护
    3、已知基类Employee只有一个构造函数,其定义如下:
    Employee::Employee( int n ) : id(n){}
    Manager 是 Employee的派生类,则下列对Manager的构造函数定义中,正确的是______。
    A.Manager :: Manager ( int n ) : id(n) {}
    B.Manager :: Manager ( int n ) : {id=n}
    C.Manager :: Manager ( int n ) : Employee(n) {}
    D.Manager :: Manager ( int n ) { Employee(n);}

    派生类构造函数提供了将参数传递给基类构造函数的途径,以保证在基类进行
    初始化时能够获得必要的数据。基类的构造函数是带有参数的,需要在派生类的
    构造函数名后面显式调用基类的构造函数。

    4、关于虚基类的描述中,错误的是______。
    A.使用虚基类可以消除由多继承产生的二义性
    B.构造派生类对象时,虚基类的构造函数只被调用一次
    C.声明“class B: virtual public A”,说明类B为虚基类
    D.建立派生类对象时,首先调用虚基类的构造函数

    答案:
    1~4 A C C C

    二、编程题
    1、定义一个长方形Rect类,派生出长方体类Cub,计算派生类对象的表面积和体积。

    代码:

    #include <iostream>
    using namespace std;
    
    class Rect						//长方形类
    {
    private :
    	int rect_length;
    	int rect_width;				//长宽
    public :
    	Rect(int l, int w)			//构造函数
    	{
    		rect_length = l;
    		rect_width = w;
    	}
    
    	
    	int getl()
    	{return rect_length;}
    	int getw()
    	{return rect_width;}
    	~Rect()
    	{}
    };
    class Cub :public Rect			//Cub类公有继承Rect类
    {
    private:
    	int cub_height;				//高
    public:
    	Cub(int l, int w, int h):Rect(l,w)
    	{
    		cub_height = h;
    	}
    	int surfaceArea()			//返回表面积
    	{
    		return (2*(getl()*getw()+getl()*cub_height+getw()*cub_height));
    	}
    	int volume()				//返回体积
    	{
    		return (getl()*getw()*cub_height);
    	}
    	~Cub()						//析构函数
    	{}
    };
    
    int main()
    {
    	Rect objFir(10,20);
    	Cub objSec(10,20,10);
    	
    	cout<<"=======表面积========
    ";
    	cout<<"	"<<objSec.surfaceArea()<<endl;
    
    	cout<<"=======体积========
    ";
    	cout<<"	"<<objSec.volume()<<endl;
    	
    	return 0;
    }
    

    运行结果:

    在这里插入图片描述

    2、定义一个Shap基类,并派生出圆球体(Sphere)和立方体类(Cube),分别求圆球体与立方体对象的表面积和体积。

    代码:

    #include <iostream>
    #include <cmath>
    using namespace std;
    
    #define PI 3.14
    
    class Shap						//Shap基类
    {
    private :
    	int length;
    public :	
    	int getl()
    	{return length;}
    };
    
    class Sphere: public Shap		//Sphere公有继承Shap基类
    {
    private:
    	int rad;
    public :	
    	Sphere(int r)
    	{
    		rad = r;
    	}
    	double surArea_1()			//体积
    	{
    		return (4/3*PI*pow(rad,3));
    	}
    	double volume_1()			//面积
    	{
    		return (4*PI*pow(rad,2));
    	}
    	~Sphere()					//析构函数
    	{}
    };
    
    class Cube :public Shap			//Cube类公有继承Shap基类
    {
    	int len;
    public:
    	Cube(int l)
    	{
    		len = l;
    	}
    	double surArea_2()
    	{
    		return (6*pow(len, 2));
    	}
    	double volume_2()
    	{
    		return (pow(len, 3));
    	}
    	~Cube()					//析构函数
    	{}
    };
    
    int main()
    {
    	//Shap  objS;				//基类对象
    	Sphere  objSp(2);		//半径为2的球体
    	Cube objC(5);			//棱长为5的立方体
    	
    	cout<<"球体的表面积:"<<objSp.surArea_1()<<"	体积为:"<<objSp.volume_1()<<endl;
    	cout<<"立方体的表面积:"<<objC.surArea_2()<<"	体积为:"<<objC.volume_2()<<endl;
    
    	return 0;
    }
    

    运行结果:

    在这里插入图片描述

    指正在求球体的表面积和体积的时候,对应输出 表面积跟体积相反了(看注释)

    千里之行,始于足下!
  • 相关阅读:
    CF1051F The Shortest Statement 题解
    CF819B Mister B and PR Shifts 题解
    HDU3686 Traffic Real Time Query System 题解
    HDU 5969 最大的位或 题解
    P3295 萌萌哒 题解
    BZOJ1854 连续攻击游戏 题解
    使用Python编写的对拍程序
    CF796C Bank Hacking 题解
    BZOJ2200 道路与航线 题解
    USACO07NOV Cow Relays G 题解
  • 原文地址:https://www.cnblogs.com/MINAIot/p/13040985.html
Copyright © 2011-2022 走看看