【码图C++程序设计(2023)】第9章 作业1

继承Point类(C++)

通过课程进入题 号:150继承Point类(C++)语言要求:C++
引入CPoint.h头文件,它的内容如下:
#include <iostream>
using namespace std;
class Point{
public:
	Point(float xx, float yy){
		x = xx;
		y =yy;
	}
private:
	float x;
	float y;
};
class Rectangle :public Point{
public:
	Rectangle(float xx,float yy,float w,float h);
	float Area();
private:
	float width;
	float high;
};

class Circle:public Point{
public:
	Circle(float xx,float yy,float r);
	float Area();
private:
	float radius;
};
实现Rectangle类和Circle类,它们都继承至Point类,派生类都具有float Area()方法,返回派生对象的面积。

Rectangle类为矩形对象,拥有长和宽属性。
Circle类为圆形,有有半径属性。

完成Rectangle类和Circle类的构造方法和Area()方法

最终两个类的使用方法如下:
Rectangle rect(1,2,3,4);
rect.Area();     //12
Circle c(5,6,7);
c.Area();      //153.86

参考答案:

#include <iostream>
using namespace std;

const float pi=3.14;//定义圆周率pi

//直接复制粘贴
class Point{
public:
	Point(float xx, float yy){
		x = xx;
		y =yy;
	}
private:
	float x;
	float y;
};

class Rectangle :public Point{
public:
	Rectangle(float xx,float yy,float w,float h);
	float Area();
private:
	float width;
	float high;
};

class Circle:public Point{
public:
	Circle(float xx,float yy,float r);
	float Area();
private:
	float radius;
};

//完成Rectangle类和Circle类的构造方法
Rectangle::Rectangle(float xx,float yy,float w,float h):Point(xx,yy)
{
	width=w,high=h;
}
Circle::Circle(float xx,float yy,float r):Point(xx,yy)
{
	radius=r;
}
//求面积的方法
float Rectangle::Area()
{
	return width*high;
}
float Circle::Area()
{
	return radius*radius*pi;
}


int main()
{
	Rectangle rect(1,2,3,4);
	rect.Area();     //12
	Circle c(5,6,7);
	c.Area();      //153.86
}

 Q。Rectangle::Rectangle(float xx,float yy,float w,float h):Point(xx,yy) 
这一行代码最后的“:Point(xx,yy) ”起什么作用?

A。这一行代码是在C++中使用构造函数的初始化列表语法,它用于初始化Rectangle对象的父类Point的成员变量。在这里,通过使用冒号(:)后跟着基类的构造函数和参数,来初始化基类的成员变量。因此,这行代码的作用是在创建Rectangle对象时,将其x坐标和y坐标设置为传递给Rectangle构造函数的xx和yy值,同时也将w和h参数存储为Rectangle对象本身的成员变量。

重载《运算符(C++)

通过课程进入题 号:163重载《运算符(C++)语言要求:C++
重载运算符 << ,使之能够使用cout将Date类对象的只以日期格式输出,Date类的定义如下,
在你的代码中需包含Date类的定义和实现。
class Date{
public:
	Date(int y=1996,int m=1,int d=1){
		day = d;
		month = m;
		year = y;
		if (m>12 || m<1)
		{
			month=1;
		}
		if (d>days(y,m))
		{
			cout<<"Invalid day!"<<endl;
			day=1;
		}
	};
	int days(int y,int m);
	void display(){
		cout<<year<<"-"<<month<<"-"<<day<<endl;
	}
private:
	int year;
	int month;
	int day;
};

你需要实现运算符 << 的重载, 输出日期的格式参见display方法。
实现Date对象的days方法,该方法返回指定年月有多少天,如days(2001,1),返回31.

最终Date类的使用方式如下,在你的代码中除了完成Date函数还需包含以下main函数:

int main(){
     int y,m,d;
	 cin>>y>>m>>d;
	 Date dt(y,m,d);
	 cout<<dt;
	 return 0;
}

例如,输入:
2013 2 1回车
输出:
2013-2-1回车

 

#include <iostream>
using namespace std;


class Date{
public:
	Date(int y=1996,int m=1,int d=1){
		day = d;
		month = m;
		year = y;
		
		//判断输入的合法性
		if (m>12 || m<1)
		{
			month=1;
		}
		if (d>days(y,m))
		{
			day=1;
		}
	}
	//实现Date对象的days方法,该方法返回指定年月有多少天,
	int days(int y,int m){
		int ddays[12]={31,28,31,30,31,30,31,31,30,31,30,31};
		//2月是个麻烦,要判断闰年否
		if((y%4==0&&y%100!=0)||y%400==0){ 
			ddays[1]=29;
		}
		else{
			ddays[1]=28;
		}
		return ddays[m-1];
	}
	
	void display(){
		cout<<year<<"-"<<month<<"-"<<day<<endl;
	}
	
	//重载
	friend ostream& operator<<(ostream&out,Date &obj){
		obj.display();
		return out;
	}
private:
	int year;
	int month;
	int day;
};

int main(){
	int y,m,d;
	cin>>y>>m>>d;
	Date dt(y,m,d);
	cout<<dt;
	return 0;
}

重载运算符部分

//重载
	friend ostream& operator<<(ostream&out,Date &obj){
		obj.display();
		return out;
	}

这段代码是一个友元函数的实现,用于输出Date类对象的信息。

首先,该函数使用了C++中的流输出对象`ostream`作为第一个参数,并将其声明为引用类型,这样可以避免不必要的复制。另外,它还使用了`Date`类对象作为第二个参数,并同样将其声明为引用类型。

在函数体内部,它首先调用了`Date`类的成员函数`display()`来显示`Date`对象的信息。

接下来,该函数将输出对象`out`返回,以便支持链式输出。这意味着,它可以像下面这样使用:

```
Date d(2022, 3, 30);
cout << d << endl;
```

上述代码会首先调用我们定义的`operator<<`函数进行输出,然后自动插入一个换行符。

总之,这段代码使得我们可以方便地将`Date`类对象输出到标准输出流或任何其它继承了`ostream`类的输出流中,从而方便了我们对日期类对象的调试和使用。

(多态)填空题04(C++)

通过课程进入题 号:161(多态)填空题04(C++)语言要求:C++
下列程序的输出结果为2,请将程序补充完整(提交时需要提交一个完整的源文件,不能只提交填空部分)
#include <iostream>
using namespace std;
class Base{
public:
	___①___void fun(){cout<<1<<endl;}
};
class Derived:public Base{
public:
	void fun(){cout<<2<<endl;}
};
int main(){
	Base *p = new Derived;
	p->fun();
	delete p;
	return 0;
}

一看就填  virtual。

虚函数 是在基类中使用关键字 virtual 声明的函数。在派生类中重新定义基类中定义的虚函数时,会告诉编译器不要静态链接到该函数。

我们想要的是在程序中任意点可以根据所调用的对象类型来选择调用的函数,这种操作被称为动态链接,或后期绑定。

#include <iostream>
using namespace std;
class Base{
public:
    virtual void fun(){cout<<1<<endl;}
};
class Derived:public Base{
public:
    void fun(){cout<<2<<endl;}
};
int main(){
    Base *p = new Derived;
    p->fun();
    delete p;
    return 0;
}

 

(多态)Set类(C++)

通过课程进入题 号:165(多态)Set类(C++)语言要求:C++
引入头文件CSet.h,它的内容如下:
#include <iostream>
using namespace std;
class Set{
private:
	int n;
	int * pS; //集合元素
public:
	Set(){n = 0;pS =NULL;}
	Set(Set &s){
		n = s.n;
		if (n !=0)
		{
			pS= new  int[n+1];
			for (int i =1;i<=n;i++) //集合的下标从1开始,集合中不能有重复元素
				pS[i] = s.pS[i];
		}
	}
	~Set(){
		if (pS)
		{
			delete []pS;
			pS = NULL;
			n =0;
		}
	}
		void ShowElement()const{ //输出集合的元素
		int temp = 0;
		for(int i=1;i<n;i++) 
		{
			for(int j=i+1;j<n;j++) 
			{
				if(pS[i] > pS[j]) 
				{
					temp = pS[i];
					pS[i] = pS[j];
					pS[j] = temp;
				}
			}
		}
		cout<<"{";
		for(int i =1;i<n;i++)
			cout <<pS[i]<<",";
		if (IsEmpty())
			cout<<"}"<<endl;
		else cout<<pS[n]<<"}"<<endl;
	}
	bool IsEmpty()const{return n?false:true;} //判断集合是否为空
	int size(){return n;}
	bool IsElement(int e)const {
		for (int i =1;i<=n;i++)
			if (pS[i] ==e)
			return true;
		return  false;
	}
	bool operator <=(const Set &s)const;//this <= s判断当前集合是否包于集合s
	bool operator ==(const Set &s)const; //判断集合是否相等
	Set & operator +=(int e);    // 向集合中增减元素e
	Set & operator -=(int e);    //删除集合中的元素e

	Set operator |(const Set &s)const;  //集合并
	Set operator &(const Set &s)const;//集合交
	Set operator -(const Set &s)const; //集合差
};
完成Set类,实现运算符的重载。
重载操作符+=,向集合中增减元素e,例如:
Set s;
s +=1;
s.ShowElement();//{1}

重载操作符-=,删除集合中元素e,例如:
Set s;
s +=1,s+=2;
s.ShowElement();//{1,2}
s -=1;
s.showElement();//{2}

重载操作符<=,判断当前集合是否包于另一个集合,例如:
Set s1,s2,s3;
s1 +=1; s2+=1;s2+=3; s3+=2;
s1 <=s2;//true
s3 <=s2//false;

重载操作符==,判断集合是否相等,例如:
Set s1 s2;
s1 == s2;//true
s1+=1;s2+=2;
s1 ==s2 ;//false;

重载操作符|,集合并,例如:
Set s1 s2;
s1+=1;s2+=2;
s1|s2 ;//{1,2}

重载操作符&,集合交,例如:
Set s1 s2;
s1+=1;s2+=2;s2+=1;
s1&s2 ;//{1}

重载操作符-,集合差,例如:
Set s1 s2;
s1+=1;s1+=3;s2+=2;s2+=1;
s1-s2 ;//{3}
#include <iostream>
using namespace std;

class Set{
private:
	int n;
	int * pS; //集合元素
public:
	Set(){n = 0;pS =NULL;}
	//构造
	Set(Set &s){
		n = s.n;
		if (n !=0)
		{
			pS= new  int[n+1];
			for (int i =1;i<=n;i++) //集合的下标从1开始,集合中不能有重复元素
				pS[i] = s.pS[i];
		}
	}
	//析构
	~Set(){
		if (pS)
		{
			delete []pS;
			pS = NULL;
			n =0;
		}
	}
	void ShowElement()const{ //输出集合的元素
		int temp = 0;
		for(int i=1;i<n;i++)
		{
			for(int j=i+1;j<n;j++)
			{
				if(pS[i] > pS[j])
				{
					temp = pS[i];
					pS[i] = pS[j];
					pS[j] = temp;
				}
			}
		}
		cout<<"{";
		for(int i =1;i<n;i++)
			cout <<pS[i]<<",";
		if (IsEmpty())
			cout<<"}"<<endl;
		else cout<<pS[n]<<"}"<<endl;  //输出的最后一个元素好像没有排序吧
	}
	bool IsEmpty()const{return n?false:true;} //判断集合是否为空
	int size(){return n;}
	bool IsElement(int e)const {
		for (int i =1;i<=n;i++)
			if (pS[i] ==e)
				return true;
		return  false;
	}
	bool operator <=(const Set &s)const;//this <= s判断当前集合是否包于集合s
	bool operator ==(const Set &s)const; //判断集合是否相等
	Set & operator +=(int e);    // 向集合中增减元素e
	Set & operator -=(int e);    //删除集合中的元素e
	
	Set operator |(const Set &s)const;  //集合并
	Set operator &(const Set &s)const;//集合交
	Set operator -(const Set &s)const; //集合差
};


bool Set::operator<=(const Set &s) const {  
	if(s.n<n){
		return false;
	}
	for(int i=1;i<=n;i++){
		if(!s.IsElement(pS[i])){
			return false;
		}
	}
	return true;
}

bool Set::operator==(const Set &s) const {
	if(s.n!=n){
		return false;
	}
	for(int i=1;i<=s.n;i++){
		if(!IsElement(s.pS[i])){
			return false;
		}
	}
	return true;
}

Set &Set::operator+=(int e) {  
	if(IsEmpty()){
		pS=new int [100];  
	}
	if(!IsElement(e)){
		n++;
		pS[n]=e;
	}
	return *this;  
}

Set &Set::operator-=(int e){
	for (int i =1;i<=n;i++)
		if (pS[i] ==e){
		for(;i<n;i++){
			pS[i]=pS[i+1];
		}n--;
		break;
	}
	return *this;
}

Set Set::operator|(const Set &s) const {
	Set S;
	S.n=n;
	S.pS = new int[n+s.n+1];
	for(int i=1;i<=n;i++){
		S.pS[i]=pS[i];
	}
	for (int i=1;i<=s.n;i++){
		if(!S.IsElement(s.pS[i])){
			S.pS[++S.n]=s.pS[i];
		}
	}
	return S;
}

Set Set::operator&(const Set &s) const {
	Set S;
	S.n=0;
	S.pS = new int[n+s.n+1];
	for (int i=1;i<=s.n;i++){
		if(IsElement(s.pS[i])){
			S.pS[++S.n]=s.pS[i];
		}
	}
	return S;
}

Set Set::operator-(const Set &s) const {
	Set S;
	S.n=0;
	S.pS = new int[n+1];
	for (int i=1;i<=n;i++){
		if(!s.IsElement(pS[i])){
			S.pS[++S.n]=pS[i];
		}
	}
	return S;
}


int main(){
	Set s1,s2;
	s1+=1;s1+=3;s2+=2;s2+=1;
	(s1-s2).ShowElement() ;
	return 0;
}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值