BJFUOJ-C++程序设计-实验4-运算符重载

A Singer类

在这里插入图片描述
在这里插入图片描述

答案:

#include<iostream>

using namespace std;

class Singer{	
private:
	string name;
	char sex;
	int age;
	double score;
public:
	string getName();	
	friend istream & operator>>(istream & in,Singer & s);
	friend ostream & operator<<(ostream & out,Singer & s);
	friend bool operator>(Singer & s1,Singer & s2);
	friend bool operator==(Singer & s1,Singer & s2);
};

string Singer::getName()
{
	return this->name;
}

istream & operator>>(istream & in,Singer & s)
{
	in>>s.name>>s.sex>>s.age>>s.score;
	return in;
}

ostream & operator<<(ostream & out,Singer & s)
{
	out<<s.name<<" "<<s.sex<<" "<<s.age<<" "<<s.score;
	return out;
}

bool operator>(Singer & s1,Singer & s2)
{
	if(s1.score>s2.score)
		return true;
	else
		return false;
}

bool operator==(Singer & s1,Singer & s2)
{
	if(s1.score==s2.score)
		return true;
	else
		return false;
}


int main()
{
	Singer s1,s2;
	cin>>s1>>s2;
	cout<<s1<<"\n"<<s2<<endl;
	
	if(s1>s2)
		cout<<s1.getName()<<"'s score is higher than "<<s2.getName()<<"'s.\n";
	else if(s1==s2)
		cout<<s1.getName()<<"'s score is equal to "<<s2.getName()<<"'s.\n";
	else
		cout<<s1.getName()<<"'s score is lower than "<<s2.getName()<<"'s.\n";

	return 0;
}

重要知识点:

简单运算符重载。

B Sales_data类

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

答案:

#include<iostream>

using namespace std;

class Sales_data {
	
//依次输入书号、销量和收入
	friend istream & operator>>(istream&, Sales_data &);
//依次输出书号、销量、收入和均价
	friend ostream & operator<<(ostream &, const Sales_data &);
	friend bool operator==(const Sales_data &, const Sales_data &);
	friend bool operator!=(const Sales_data &, const Sales_data &);
// for "+", assume that both objects refer to the same book
	friend Sales_data operator+(const Sales_data &, const Sales_data &);

public:
	Sales_data(): units_sold(0), revenue(0.0) {}
	Sales_data(const string & s, unsigned n, double r): bookNo(s), units_sold(n), revenue(r) {}
	string get_bookNo() const;
	// for "+=", assume that both objects refer to the same book
	Sales_data & operator+=(const Sales_data &);

private:
	double avg_price() const;  //均价,等于收入除以销量
	string bookNo;        //书号
	unsigned units_sold; //销量
	double revenue;      //收入
};

double Sales_data::avg_price() const
{
	return revenue/units_sold;
}

istream & operator>>(istream& is,Sales_data & s)
{
	is>>s.bookNo>>s.units_sold>>s.revenue;	
	
	return is;
} 
ostream & operator<<(ostream & os, const Sales_data & s)
{
	os<<s.bookNo<<" "<<s.units_sold<<" "<<s.revenue<<" "<<s.avg_price();
	return os;
}

bool operator==(const Sales_data & s1, const Sales_data & s2)
{
	if(s1.bookNo==s2.bookNo)
		return 1;
	else
		return 0;
}

bool operator!=(const Sales_data &s1, const Sales_data &s2)
{
	if(s1.bookNo==s2.bookNo)
		return 0;
	else
		return 1;
}

Sales_data operator+(const Sales_data &s1, const Sales_data &s2)
{
	Sales_data ts;
	ts.bookNo=s1.bookNo;
	ts.units_sold=s1.units_sold+s2.units_sold;
	ts.revenue=s1.revenue+s2.revenue;
	return ts;
}

string Sales_data::get_bookNo() const
{
	return this->bookNo;
}

Sales_data & Sales_data::operator+=(const Sales_data & s)
{
	this->revenue+=s.revenue;
	this->units_sold+=s.units_sold;
	return *this;
}

int main(){
	Sales_data item1,item2;

	while(cin>>item1>>item2){
		cout<<item1<<"\n"<<item2<<"\n";
		if(item1==item2)
			cout<<item1.get_bookNo()<<" equals "<<item2.get_bookNo()<<"\n";
		if(item1!=item2)
			cout<<item1.get_bookNo()<<" doesn't equal "<<item2.get_bookNo()<<"\n";
		cout<<(item1+item2)<<"\n";
		item1 += item2;
		cout<<item1<<"\n";
	}

	return 0;
}

重要知识点:

麻烦一点的简单运算符重载。

C Complex类

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

答案:

#include<iostream>
using namespace std;

class Complex
{
private:
	double x;
	double y;

public:
	Complex(double x = 0.0, double y = 0.0);
	Complex & operator+=(const Complex &);
	Complex & operator-=(const Complex &);
	Complex & operator*=(const Complex &);
	Complex & operator/=(const Complex &);

	friend Complex operator+(const Complex &, const Complex &);
	friend Complex operator-(const Complex &, const Complex &);
	friend Complex operator*(const Complex &, const Complex &);
	friend Complex operator/(const Complex &, const Complex &);
	friend bool operator==(const Complex &, const Complex &);
	friend bool operator!=(const Complex &, const Complex &);
	friend ostream & operator<<(ostream &, const Complex &);
	friend istream & operator>>(istream &, Complex &);
};

Complex::Complex(double x, double y)
{
	this->x=x;
	this->y=y;
}

Complex & Complex::operator+=(const Complex & c)
{
	this->x+=c.x;
	this->y+=c.y;
	return *this;
}

Complex & Complex::operator-=(const Complex & c)
{
	this->x-=c.x;
	this->y-=c.y;
	return *this;
}

//需要将临时变量保存原始数值,然后再进行计算操作
Complex & Complex::operator*=(const Complex & c)
{
	double tx=x;
	double ty=y;
	x=tx*c.x-ty*c.y;
	y=tx*c.y+ty*c.x;
	return *this;
}

Complex & Complex::operator/=(const Complex & c)
{
	double tx=x;
	double ty=y;
	this->x=(tx*c.x+ty*c.y)/(c.x*c.x+c.y*c.y);
	this->y=(ty*c.x-tx*c.y)/(c.x*c.x+c.y*c.y);
	return *this;
}

Complex operator+(const Complex &c1, const Complex &c2)
{
	Complex tc;
	tc.x=c1.x+c2.x;
	tc.y=c1.y+c2.y;
	return tc;
}

Complex operator-(const Complex &c1, const Complex &c2)
{
	Complex tc;
	tc.x=c1.x-c2.x;
	tc.y=c1.y-c2.y;
	return tc;
}

Complex operator*(const Complex &c1, const Complex &c2)
{
	Complex tc;
	tc.x=c1.x*c2.x-c1.y*c2.y;
	tc.y=c1.x*c2.y+c1.y*c2.x;
	return tc;
}

Complex operator/(const Complex &c1, const Complex &c2)
{
	Complex tc; 
	tc.x=(c1.x*c2.x+c1.y*c2.y)/(c2.x*c2.x+c2.y*c2.y);
	tc.y=(c1.y*c2.x-c1.x*c2.y)/(c2.x*c2.x+c2.y*c2.y);
	return tc;
}

bool operator==(const Complex &c1, const Complex &c2)
{
	if(c1.x==c2.x)
		return 1;
	else
		return 0; 
}

bool operator!=(const Complex &c1, const Complex &c2)
{
	if(c1.x==c2.x)
		return 0;
	else
		return 1;	
}

ostream & operator<<(ostream &os, const Complex &c)
{
	os<<c.x<<" + "<<c.y<<"i";
	return os;
}

istream & operator>>(istream &is, Complex &c)
{
	is>>c.x>>c.y;
	return is;
}
	
int main()
{
Complex c1, c2;

	cin >> c1 >> c2;
	cout << "c1 = " << c1 << "\n" << "c2 = " << c2 << endl;
	cout << "c1+c2 = " << c1 + c2 << endl;
	cout << "c1-c2 = " << c1 - c2 << endl;
	cout << "c1*c2 = " << c1 * c2 << endl;
	cout << "c1/c2 = " << c1 / c2 << endl;
	cout << (c1 += c2) << endl;
	cout << (c1 -= c2) << endl;
	cout << (c1 *= c2) << endl;
	cout << (c1 /= c2) << endl;
	cout << (c1 == c2) << " " << (c1 != c2) << endl;

	return 0;
}



重要知识点:

很经典全面的运算符重载实例,注意一下实现乘除法时需要将临时变量保存原始数值,然后再进行计算操作。

D String类 (重点学习)

描述:

实现以下String类:

class String
{
private:
char * s;
public:
String();
String(const char *);
String(const String &);
~String();
String & operator=(const char *);
String & operator=(const String &);
String operator+(const char *);
String operator+(const String &);
String & operator+=(const char *);
String & operator+=(const String &);
friend istream & operator>>(istream &, String &);
friend ostream & operator<<(ostream &, const String &);
friend bool operator==(const String &, const char *);
friend bool operator==(const String &, const String &);
friend bool operator!=(const String &, const char *);
friend bool operator!=(const String &, const String &);
};

使用以下main函数进行测试:

int main()
{
String s;
s += “hello”;
cout<<s<<endl;
String s1(“String1”);
String s2("copy of ");
s2 += “String1”;
cout << s1 << “\n” << s2 << endl;
String s3;
cin >> s3;
cout << s3 << endl;
String s4(“String4”), s5(s4);
cout << (s5 == s4) << endl;
cout << (s5 != s4) << endl;
String s6("End of "), s7(“my string.”);
s6 += s7;
cout << s6 << endl;
return 0;
}

输入:

s3的值

输出:

见示例与主函数

输入样例:

   String3

输出样例:

hello
String1
copy of String1
String3
1
0
End of my string.

答案:

#include<iostream>
#include<cstring>
using namespace std;

class String
{
private:
	char* s;

public:
	String();
	String(const char*);
	String(const String&);
	~String();

	String& operator=(const char*);
	String& operator=(const String&);
	String operator+(const char*);
	String operator+(const String&);
	String& operator+=(const char*);
	String& operator+=(const String&);

	friend istream& operator>>(istream&, String&);
	friend ostream& operator<<(ostream&, const String&);
	friend bool operator==(const String&, const char*);
	friend bool operator==(const String&, const String&);
	friend bool operator!=(const String&, const char*);
	friend bool operator!=(const String&, const String&);
};

String::String()
{
	s = new char[1];
	s[0]='\0';
	//s=NULL;
}

String::String(const char* tc)
{
	s = new char[strlen(tc) + 1];
	strcpy(s, tc);
}

String::String(const String& ts)
{
	s = new char[strlen(ts.s) + 1];
	strcpy(s, ts.s);
}

String::~String()
{
	delete[] s;
}

String& String::operator=(const char* tc)
{
	s = new char[strlen(tc) + 1];
	strcpy(s, tc);
	return *this;
}

String& String::operator=(const String& ts)
{
	s = new char[strlen(ts.s) + 1];
	strcpy(s, ts.s);
	return *this;
}

String String::operator+(const char* tc)
{
	String news;
	news.s = new char[strlen(s) + strlen(tc) + 1];
	strcpy(news.s, s);
	strcat(news.s, tc);
	return news;
}

String String::operator+(const String& ts)
{
	String news;
	news.s = new char[strlen(s) + strlen(ts.s) + 1];
	strcpy(news.s, s);
	strcat(news.s, ts.s);
	return news;
}

String& String::operator+=(const char* tc)
{
	char* news = new char[strlen(s) + strlen(tc) + 1];
	strcpy(news, s);
	strcat(news, tc);
	delete[] s;
	s = news;
	return *this;
}

String& String::operator+=(const String& ts)
{
	char* news = new char[strlen(s) + strlen(ts.s) + 1];
	strcpy(news, s);
	strcat(news, ts.s);
	delete[] s;
	s = news;
	return *this;
}

istream& operator>>(istream& is, String& ts)
{

	char temp[100];
	is >> temp;
	delete[] ts.s;
	ts.s = new char[strlen(temp) + 1];
    strcpy(ts.s, temp);
	return is;
}

ostream& operator<<(ostream& os, const String& ts)
{
	os << ts.s;
	return os;
}

bool operator==(const String& ts, const char* tc)
{
	return (strcmp(ts.s, tc) == 0);
}

bool operator==(const String& ts1, const String& ts2)
{
	return (strcmp(ts1.s, ts2.s) == 0);
}
bool operator!=(const String& ts, const char* tc)
{
	return !(strcmp(ts.s, tc) == 0);
}

bool operator!=(const String& ts1, const String& ts2)
{
	return !(strcmp(ts1.s, ts2.s) == 0);
}


int main()
{
	String s;
	s += "hello";
	cout << s << endl;
	String s1("String1");
	String s2("copy of ");
	s2 += "String1";
	cout << s1 << "\n" << s2 << endl;
	String s3;
	cin >> s3;
	cout << s3 << endl;
	String s4("String4"), s5(s4);
	cout << (s5 == s4) << endl;
	cout << (s5 != s4) << endl;
	String s6("End of "), s7("my string.");
	s6 += s7;
	cout << s6 << endl;

	return 0;
}

重要知识点:

1.首先注意到成员是个字符指针,要想到new与delete、浅拷贝与深拷贝相关知识。
2.无参构造函数:

String::String()
{
	s = new char[1];
	s[0]='\0';
	//s=NULL;
}
要为类的成员变量s动态分配内存来存储字符串。由于字符串是以\0结尾的字符数组,
所以需要为s分配一个长度为1的字符数组,并将数组的第一个元素设为字符’\0’,以表示空字符串的结束。
这样可以确保s成员变量始终以空字符串结尾,从而正确表示一个空的String对象。

而s=NULL不行:因为String类表示的是一个字符串对象,
如果将s赋值为NULL,那么s将指向空地址,而不是一个空字符串。这样会导致后续对s操作时出现错误。

3.两个拷贝构造函数:

String::String(const char* tc)
{
	s = new char[strlen(tc) + 1];
	strcpy(s, tc);
}

String::String(const String& ts)
{
	s = new char[strlen(ts.s) + 1];
	strcpy(s, ts.s);
}

首先为s申请足够的空间,再通过strcpy()实现字符串的深拷贝。

4.注意析构函数中使用delete。
5.对=重载时要删除原来的值;
6.对+重载时逻辑为创造一个新对象,strcpy前一个字符串,再strcat加上后一个字符串。最后返回这个新对象。
7.+=与+区别:
创建的是char* 而非string类对象(最后直接赋予String.s);
s = news;前delete原先对象。
最后返回的是自己。
8.>>的重载:
直接is>>ts.s也能通过但并不符合常理,应该按上文写法;
9.strcmp的返回值;(为0为相等)

E CheckedPtr

在这里插入图片描述
在这里插入图片描述

答案:

#include<iostream>
using namespace std;

class CheckedPtr
{
public:
	CheckedPtr(int * b, int * e) : beg(b), end(e), curr(b) {  }
	CheckedPtr & operator ++(); // prefix ++
	CheckedPtr & operator --(); // prefix --
	CheckedPtr   operator ++(int); // postfix ++
	CheckedPtr   operator --(int); // postfix --
	int * GetBeg();
	int * GetEnd();
	int * GetCurr();

private:
	int * beg;  // pointer to beginning of the array
	int * end;  // one past the end of the array
	int * curr; // current position within the array
};

CheckedPtr & CheckedPtr::operator ++()
{
	++curr;
	return *this;
}

CheckedPtr & CheckedPtr::operator --()
{
	--curr;
	return *this;
}

CheckedPtr   CheckedPtr::operator ++(int)
{
	CheckedPtr temp = *this;
    ++curr;
    return temp;
}

CheckedPtr   CheckedPtr::operator --(int)
{
	CheckedPtr temp = *this;
    --curr;
    return temp;
}

int * CheckedPtr::GetBeg()
{
	return beg;
}

int * CheckedPtr::GetEnd()
{
	return end;
}

int * CheckedPtr::GetCurr()
{
	return curr;
}

int main(){
	int n;
	cin>>n;
	int * array = new int[n];

	for(int i=0;i<n;i++)
		cin>>array[i];
	CheckedPtr cp(array, array+n);
	for(;cp.GetCurr()<cp.GetEnd();cp++)
		cout<<*cp.GetCurr()<<" ";
	cout<<endl;
	for(--cp;cp.GetCurr()>cp.GetBeg();cp--)
		cout<<*cp.GetCurr()<<" ";
	cout<<*cp.GetCurr()<<endl;
	delete [] array;

return 0;

}

重要知识点:

这里主要关注前缀++/–与后缀++/–的写法及其区别。

  • 23
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值