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;
    }
    

    运行结果:

    在这里插入图片描述

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

    千里之行,始于足下!
  • 相关阅读:
    Ubuntu 12.04下GAMIT10.40安装说明
    GAMIT 10.50在Ubuntu 12.04系统下的安装
    tomcat 5.5 动态加载类
    GAMIT 10.50在Ubuntu 12.04系统下的安装
    RHCE 系列(九):如何使用无客户端配置 Postfix
    Nginx+Keepalived(带Nginx监控脚本)
    黑马程序员_java08_多线程
    oracle 表类型变量的使用
    如何在win7系统中安装redis
    bzoj 2816: [ZJOI2012]网络(splay)
  • 原文地址:https://www.cnblogs.com/MINAIot/p/13040985.html
Copyright © 2011-2022 走看看