面向对象程序设计|运算符重载

目录

题目一:分数的加减乘除(运算符重载)

题目二:四进制加法(运算符重载)

题目三:人民币输出(输入输出运算符重载)

题目四:字符串比较(运算符重载)

题目五:矩形关系(运算符重载)

题目六:矩阵(运算符重载)

题目七:X的放大与缩小(运算符重载)

题目八:集合(运算符重载)

题目九:OOP CString字符串拼接(深拷贝与运算符重载)


题目一:分数的加减乘除(运算符重载)

题目描述:

Fraction类的基本形式如下:

要求如下:

1.实现Fraction类;common_divisor()和contracted()函数体可为空,不实现具体功能。

2.编写main函数,初始化两个Fraction对象的,计算它们之间的加减乘除。

输入要求:

第1行:依次输入第1个和第2个Fraction对象的分子和分母值。

输出要求:

每行依次分别输出加减乘除计算后的Fraction对象(直接输出分数值,不需要约简)。

输入样例:

1 3 2 5

输出样例:

fraction=11/15
fraction=-1/15
fraction=2/15
fraction=5/6

代码示例:

#include<iostream>
#include<iomanip>
#include<cstring>
#include<string> 
#include<cmath>
#include<algorithm>
using namespace std;

class Fraction {
private:
	int numerator, denominator;
	int common_divisor() {};
	int contracted() {};
public:
	Fraction(int x = 0, int y = 1) :numerator(x), denominator(y) {}
	Fraction(Fraction& fra)//拷贝构造函数
	{
		numerator = fra.numerator;
		denominator = fra.denominator;
	}
	Fraction operator + (Fraction& fra)//类内运算符重载:类名 + operator + 需要重载的运算符(类引用)
	{
		Fraction f;
		f.numerator = numerator * fra.denominator + fra.numerator * denominator;
		f.denominator = denominator * fra.denominator;
		return f;
	}
	Fraction operator - (Fraction& fra)
	{
		Fraction f;
		f.numerator = numerator * fra.denominator - fra.numerator * denominator;
		f.denominator = denominator * fra.denominator;
		return f;
	}
	Fraction operator * (Fraction& fra) {
		Fraction f;
		f.numerator = numerator * fra.numerator;
		f.denominator = denominator * fra.denominator;
		return f;
	}
	Fraction operator / (Fraction& fra)
	{
		Fraction f;
		f.numerator = numerator * fra.denominator;
		f.denominator = denominator * fra.numerator;
		return f;
	}
	void Set(int x, int y)
	{
		numerator = x;
		denominator = y;
	}
	void disp() {
		cout << "fraction=" << numerator << "/" << denominator << endl;
	}
};
int main()
{
	int a, b;
	cin >> a >> b;
	Fraction f1(a, b);
	cin >> a >> b;
	Fraction f2(a, b);
	Fraction f3;
	f3 = f1 + f2;
	f3.disp();
	f3 = f1 - f2;
	f3.disp();
	f3 = f1 * f2;
	f3.disp();
	f3 = f1 / f2;
	f3.disp();
	return 0;
}

题目二:四进制加法(运算符重载)

题目描述:

定义一个四进制的类,重定义“+”号实现四进制数的累加。

输入要求:

第一行输入所需要的四进制数的个数

第二行开始,依次输入四进制数

输出要求:

所有输入四进制数累加的和

输入样例:

3
13
2
21

输出样例:

102

代码示例:

#include<iostream>
#include<iomanip>
#include<cstring>
#include<string> 
#include<cmath>
#include<algorithm>
using namespace std;


class Quaternary
{
private:
	int num;
public:
	Quaternary(int nn = 0) :num(nn) {}
	void Set(int nn)
	{
		num = nn;
	}
	Quaternary operator+(Quaternary& rhs)
	{
		int sum, a;
		int n = 0;
		int total = 0;
		sum = num + rhs.num;
		a = sum;
		while (a)//十进制转化成四进制的方法
		{
			a /= 10;
			n++;
		}
		for (int i = 0; i < n + 1; i++)
		{
			if (sum % 10 >= 4)
			{
				sum = (sum / 10 + 1) * 10 + sum % 10 - 4;
			}
			total += sum % 10 * pow(10, i);
			sum /= 10;
		}
		Quaternary qu(total);
		return qu;
	}
	void print() {
		cout << num << endl;
	}
};
int main() {
	int n, x;
	cin >> n;
	Quaternary* q;
	Quaternary qua;
	q = new Quaternary[n];
	for (int i = 0; i < n; i++)
	{
		cin >> x;
		q[i].Set(x);//动态内存分配的初始化
	}
	for (int i = 0; i < n; i++)
	{
		qua = qua + q[i];
	}
	qua.print();
}

注意四进制转化成十进制再转化为四进制的算法;

题目三:人民币输出(输入输出运算符重载)

题目描述:

定义一个人民币类,包括元、角、分三个非负整数属性,操作包括输入和输出

输入通过重载运算符>>实现,接收一个浮点数参数(精度为小数点后两位),并转化为元、角、分,例如输入1.23元,转为1元、2角、3分

输出通过重载运算符<<实现,对元角分进行输出,具体格式看示例

由于OJ编译器对double强制类型转换成int的处理精度有偏差,建议加0.005处理(例如数据1.38,由于误差,在内存中的存储值为1.379999)

输入要求:

第一行输入t表示有t个实例

第二行起,输入t个正浮点数,带两位小数,每个数值表示以元为单位的人民币金额

输出要求:

每行输出把浮点数的人民币金额,转化为元角分的整数格式,具体看输出

输入样例:

2
2.45
1.38

输出样例:

yuan=2 jiao=4 fen=5
yuan=1 jiao=3 fen=8

代码示例:

#include<iostream>
#include<iomanip>
#include<cstring>
#include<string> 
#include<cmath>
#include<algorithm>
using namespace std;

class RMB
{
private:
	float money;
	int yuan;
	int jiao;
	int fen;
public:
	RMB() {}
	friend istream& operator>>(istream& in, RMB& rhs);//输入输出流的运算符重载,记住格式
	friend ostream& operator<<(ostream& out, RMB& rhs);//friend ostream/istream & operator <</>> (ostream/istream & ,类引用)
};

istream& operator>>(istream& in, RMB& rhs)
{
	in >> rhs.money;//直接输入数据至类内
	rhs.yuan = (int)rhs.money;
	rhs.jiao = ((int)(rhs.money * 10)) % 10;
	rhs.fen = ((int)(rhs.money * 100)) % 10;
	return in;
}

ostream& operator<<(ostream& out, RMB& rhs)
{
	out << "yuan=" << rhs.yuan << " " << "jiao=" << rhs.jiao << " " << "fen=" << rhs.fen << endl;
	return out;
}

int main()
{
	int t;
	cin >> t;
	while (t--)
	{
		RMB rmb;
		cin >> rmb;
		cout << rmb;
	}
	return 0;
}

注意输入输出运算符重载的格式,记住就行了!

题目四:字符串比较(运算符重载)

题目描述:

定义一个字符串类str,用来存放不定长的字符串,重载运算符"= ="、"<"、">",用于两个字符窜的等于、小于和大于的比较运算。

要求如下:

1.实现str类;

2.编写main函数,初始化三个str对象A、B、C,然后用这三个对象去测试重载的运算符。如果A>B,则输出A的字符串;否则输出B的字符串。如果A<C,则输出A的字符串;否则输出C的字符串。如果B==C,则输出B的字符串;否则输出C的字符串。

输入要求:

输入3行,每行为一个字符串,初始化三个str对象。

输出要求:

输出比较之后的结果字符串,每个比较的结果一行。

输入样例:

i am a student
i love China
i love China

输出样例:

i love China
i am a student
i love China

代码示例:

#include<iostream>
#include<iomanip>
#include<cstring>
#include<string> 
#include<cmath>
#include<algorithm>
using namespace std;

class str
{
    char* p;
public:
    str() = default;//初始化构造
    str(const char* s)
    {
        p = new char[strlen(s) + 1];
        strcpy(p, s);//s串赋给p指针
    }

    friend bool operator > (str& lhs, str& rhs)//友元类型的运算符重载
    {
        return strcmp(lhs.p, rhs.p) > 0;
    }

    friend bool operator < (str& lhs, str&rhs)
    {
        return strcmp(lhs.p, rhs.p) < 0;
    }
    friend bool operator == (str& lhs, str& rhs)
    {
        return strcmp(lhs.p, rhs.p) == 0;
    }
    void show()
    {
        cout << p << endl;
    }
};

int main()
{
    string s1, s2, s3;

    getline(cin, s1);//输入带空格的字符串
    getline(cin, s2);
    getline(cin, s3);

    str A(s1.c_str()), B(s2.c_str()), C(s3.c_str());//c_str() 函数可以将 const string* 类型 转化为 const char* 类型

    if (A > B)
        A.show();
    else
        B.show();

    if (A < C)
        A.show();
    else
        C.show();

    if (B == C)
        B.show();
    else
        C.show();
    return 0;
}

注意友元函数运算符重载与类内运算符重载的区别,前者是(两个引用),后者是(一个引用);以及c_str()函数的用法,注意加string头文件!!

题目五:矩形关系(运算符重载)

题目描述:

假设坐标采用二维平面坐标。

定义点类CPoint,包含属性x,y(整型)。方法有:带参构造函数,getX,getY分别返回点的x坐标,y坐标。

定义矩形类CRectangle,包含属性:矩形的左上角坐标leftPoint,右下角坐标rightPoint。类中方法有:

1)带参构造函数,初始化矩形的左上角、右下角

2)重载>运算符,参数为CPoint点对象,假设为p,若p在矩形内,返回true,否则返回false。

3)重载>运算符,第一个矩形若包含第二个矩形(部分边界可以相等),返回true,否则返回false。(要求该函数调用2)实现)

4)重载==运算符,判断两个矩形是否一致,返回true或false。

5)重载*运算符,判断两个矩形是否有重叠部分,返回true或false。

6)重载类型转换运算符,计算矩形的面积并返回,面积是整型。

7)重载<<运算符,输出矩形的两个角坐标和面积,具体格式见样例。

输入2个矩形,计算面积,判断矩形的关系。主函数如下,不可修改。

 可根据需要,添加构造函数和析构函数。

输入要求:

测试次数

每组测试数据如下:

矩形1的左上角、右下角坐标

矩形2的左上角、右下角坐标

输出要求:

每组测试数据输出如下,中间以空行分隔:

矩形1的坐标和面积(具体格式见样例)

矩形2的坐标和面积(具体格式见样例)

矩形1和矩形2的关系(矩形1包含矩形2、矩形2包含矩形1、矩形2和矩形1相等、矩形1和矩形2相交、矩形1和矩形2不相交)

输入样例:

2
1 4 4 1
2 3 3 2
1 4 4 1
0 3 5 2

输出样例:

矩形1:1 4 4 1 9
矩形2:2 3 3 2 1
矩形1包含矩形2

矩形1:1 4 4 1 9
矩形2:0 3 5 2 5
矩形1和矩形2相交

代码示例:

#include<iostream>
#include<iomanip>
#include<cstring>
#include<string> 
#include<cmath>
#include<algorithm>
using namespace std;

class Point
{
    int x, y;
public:
    Point(int xx, int yy) :x(xx), y(yy) {}
    int getX() { return x; }
    int getY() { return y; }
};

class Rectangle
{
private:
    Point leftPoint, rightPoint;
public:
    Rectangle(int xv1, int yv1, int xv2, int yv2) :leftPoint(xv1, yv1), rightPoint(xv2, yv2) {}
    bool operator > (Point& p)
    {
        if (p.getX() >= leftPoint.getX() && p.getX() <= rightPoint.getX() && p.getY() <= leftPoint.getY() && p.getY() >= rightPoint.getY())
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    bool operator > (Rectangle& rhs)
    {
        if (*this > rhs.leftPoint && *this > rhs.rightPoint)//此处调用上一个运算符重载
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    bool operator == (Rectangle& rhs)
    {
        if (this->rightPoint.getX() == rhs.rightPoint.getX() && this->leftPoint.getY() == rhs.leftPoint.getY() && this->rightPoint.getX() == rhs.rightPoint.getX() && this->rightPoint.getY() == rhs.rightPoint.getY())
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    bool operator * (Rectangle& rhs)
    {
        if (rhs.leftPoint.getX() > rightPoint.getX() || rhs.leftPoint.getY() < rightPoint.getY() || rhs.rightPoint.getX() < leftPoint.getX() || rhs.rightPoint.getY() > leftPoint.getY())
        {
            return false;
        }
        else
        {
            return true;
        }
    }
    operator int()//int类型的运算符重载
    {
        int area = (rightPoint.getX() - leftPoint.getX()) * (leftPoint.getY() - rightPoint.getY());
        return area;
    }
    friend ostream& operator<<(ostream& out, Rectangle& rhs);
};

ostream& operator<<(ostream& out, Rectangle& rhs)
{
    out << rhs.leftPoint.getX() << " " << rhs.leftPoint.getY() << " " << rhs.rightPoint.getX() << " " << rhs.rightPoint.getY();
    return out;
}

int main()
{
    int t, x1, x2, y1, y2;
    cin >> t;
    while (t--)
    {
        cin >> x1 >> y1 >> x2 >> y2;
        Rectangle rect1(x1, y1, x2, y2);
        cin >> x1 >> y1 >> x2 >> y2;
        Rectangle rect2(x1, y1, x2, y2);

        cout << "矩形1:" << rect1 << " " << (int)rect1 << endl;
        cout << "矩形2:" << rect2 << " " << (int)rect2 << endl;

        if (rect1 == rect2)
        {
            cout << "矩形1和矩形2相等" << endl;
        }
        else if (rect2 > rect1)
        {
            cout << "矩形2包含矩形1" << endl;
        }
        else if (rect1 > rect2)
        {
            cout << "矩形1包含矩形2" << endl;
        }
        else if (rect1 * rect2)
        {
            cout << "矩形1和矩形2相交" << endl;
        }
        else
        {
            cout << "矩形1和矩形2不相交" << endl;
        }
        cout << endl;
    }
    return 0;
}

运算符重载一定要有返回值!!

题目六:矩阵(运算符重载)

题目描述:

下面主函数和Array类完成矩阵的输入、输出。请补齐Array类中需要的成员函数。

注意:主函数和CArray类已给代码不可修改,只可在CArray类中添加新的成员函数。修改已改代码不计分。

提示:根据已给代码分析CArray需要重载哪些运算符?

输入要求:

测试次数

每组测试数据格式如下:

正整数n、m,分表表示矩阵的行、列

n*m行整数数据

输出要求:

每组测试数据输出矩阵数据两次,具体输出格式见样例。

输入样例:

2
3 3
1 2 3
4 5 6
7 8 9
2 4
10 20 30 40
50 60 70 80

输出样例:

MatrixA:
1 2 3 
4 5 6 
7 8 9 
MatrixB:
1 2 3 
4 5 6 
7 8 9 
MatrixA:
10 20 30 40 
50 60 70 80 
MatrixB:
10 20 30 40 
50 60 70 80 

代码示例:

#include<iostream>
#include<iomanip>
#include<cstring>
#include<string> 
#include<cmath>
#include<algorithm>
using namespace std;

class CArray
{
private:
    int n, m;
    int** data;
public:
    CArray() {}
    CArray(int nValue, int mValue) :n(nValue), m(mValue)
    {
        data = new int* [n];
        for (int i = 0; i < n; i++)
            data[i] = new int[m];
    }
    CArray(const CArray& a)
    {
        n = a.n;
        m = a.m;
        data = new int* [n];
        for (int i = 0; i < n; i++)
            data[i] = new int[m];
        for (int i = 0; i < n; ++i)
            for (int j = 0; j < m; j++)
                data[i][j] = a.data[i][j];
    }
    ~CArray()
    {
        for (int i = 0; i < n; i++)
            delete[]data[i];
        delete[]data;
    }
    CArray& operator = (const CArray& rhs)// = 运算符重载
    {
        n = rhs.n;
        m = rhs.m;
        data = new int* [n];
        for (int i = 0; i < n; i++)
            data[i] = new int[m];
        for (int i = 0; i < n; ++i)
            for (int j = 0; j < m; j++)
                data[i][j] = rhs.data[i][j];
        return *this;
    }
    int* operator [](const int x)//两个特殊的运算符重载
    {
        return data[x];
    }
    int operator () (int x, int y)
    {
        return data[x][y];
    }
};


int main()
{
    int t;
    int n, m;
    int i, j;
    cin >> t;
    while (t--)
    {
        cin >> n >> m;
        CArray matrixA(n, m);
        for (i = 0; i < n; ++i)
            for (j = 0; j < m; j++)
                cin >> matrixA[i][j];
        cout << "MatrixA:" << endl;
        for (i = 0; i < n; ++i)
        {
            for (j = 0; j < m; j++)
            {
                cout << matrixA(i, j) << " ";//重载()符号
            }
            cout << endl;
        }
        cout << "MatrixB:" << endl;
        CArray matrixB;
        matrixB = matrixA;
        for (i = 0; i < n; i++)
        {
            for (j = 0; j < m; j++)
            {
                cout << matrixB[i][j] << " ";//重载[]符号,本质是返回了一个指针
            }
            cout << endl;
        }
    }
    return 0;
}

特殊的运算符重载

题目七:X的放大与缩小(运算符重载)

题目描述:

X字母可以放大和缩小,变为n行X(n=1,3,5,7,9,...,21)。例如,3行x图案如下:

现假设一个n行(n>0,奇数)X图案,遥控器可以控制X图案的放大与缩小。遥控器有5个按键,1)show,显示当前X图案;2)show++, 显示当前X图案,再放大图案,n+2;3)++show,先放大图案,n+2,再显示图案;4)show--,显示当前X图案,再缩小图案,n-2;5)--show,先缩小图案,n-2,再显示图案。假设X图案的放大和缩小在1-21之间。n=1时,缩小不起作用,n=21时,放大不起作用。

用类CXGraph表示X图案及其放大、缩小、显示。主函数模拟遥控器,代码如下,不可修改。请补充CXGraph类的定义和实现。

输入要求:

第一行n,大于0的奇数,X图案的初始大小。

第二行,操作次数

每个操作一行,为show、show++、show--、--show、++show之一,具体操作含义见题目。

输出要求:

对每个操作,输出对应的X图案。

输入样例:

3
5
show
show++
show++
++show
--show

输出样例:

XXX
 X
XXX

XXX
 X
XXX

XXXXX
 XXX
  X
 XXX
XXXXX

XXXXXXXXX
 XXXXXXX
  XXXXX
   XXX
    X
   XXX
  XXXXX
 XXXXXXX
XXXXXXXXX

XXXXXXX
 XXXXX
  XXX
   X
  XXX
 XXXXX
XXXXXXX

代码示例:

#include<iostream>
#include<iomanip>
#include<cstring>
#include<string> 
#include<cmath>
#include<algorithm>
using namespace std;

class XGraph
{
private:
	int n;
public:
	XGraph(int nn) :n(nn) {}
	XGraph(XGraph& rhs)
	{
		n = rhs.n;
	}
	XGraph& operator++()//前置++,返回的是引用;前置用引用则是为了不产生临时变量,可以减少内存的消耗。
	{
		if (this->n <= 19)
		{
			this->n += 2;
		}
		return *this;
	}
	XGraph operator++(int)//后置++,返回的是临时对象,因为后置的时候原来的对象已经被++改变了。
	{					  //后置的函数的声明里面参数列表中比前置多了一个int,这里的int其实是作为区分前后置的标志,在函数体里面并没有直接地用到。
		XGraph temp = *this;
		if (this->n <= 19)
		{
			this->n += 2;
		}
		return temp;
	}
	XGraph& operator--()//原理与++或--相同
	{
		if (this->n >= 3)
		{
			this->n -= 2;
		}
		return *this;
	}
	XGraph operator--(int)
	{
		XGraph temp = *this;
		if (this->n >= 3)
		{
			this->n -= 2;
		}
		return temp;
	}
	friend ostream& operator<<(ostream& out, const XGraph& rhs);//输出运算符重载,记住特定的格式
};

ostream& operator<<(ostream& out, const XGraph& rhs)
{
	for (int i = 0; i < (rhs.n + 1) / 2; i++)
	{
		for (int j = 0; j < i; j++)
		{
			cout << " ";
		}
		for (int j = i; j < rhs.n - i; j++)
		{
			cout << "X";
		}
		cout << endl;
	}
	for (int i = (rhs.n + 1) / 2; i < rhs.n; i++)
	{
		for (int j = rhs.n - 1 - i; j > 0; j--)
		{
			cout << " ";
		}
		for (int j = rhs.n - 1 - i; j <= i; j++)
		{
			cout << "X";
		}
		cout << endl;
	}
	return out;
}


int main()
{
	int t, n;
	string command;
	cin >> n;
	XGraph xGraph(n);
	cin >> t;
	while (t--)
	{
		cin >> command;
		if (command == "show++")
		{
			cout << xGraph++ << endl;
		}
		else if (command == "++show")
		{
			cout << ++xGraph << endl;
		}
		else if (command == "show--")
		{
			cout << xGraph-- << endl;
		}
		else if (command == "--show")
		{
			cout << --xGraph << endl;
		}
		else if (command == "show")
			cout << xGraph << endl;

	}
	return 0;
}

注意区分前++ / --和后++ / -- 的区别,前置返回引用,后置返回临时对象!

题目八:集合(运算符重载)

题目描述:

集合是由一个或多个确定的元素所构成的整体。集合的运算有并、交、相对补等。

集合A和集合B的交集:由属于A且属于B的相同元素组成的集合。

集合A和集合B的并集:由所有属于集合A或属于集合B的元素所组成的集合。

集合B关于集合A的相对补集,记做A-B:由属于A而不属于B的元素组成的集合。

假设集合A={10,20,30},集合B={1,10,50,8}。则A与B的并是{10,20,30,1,50,8},A与B的交是{10},B关于A的相对补集是{20,30}。

定义整数集合类CSet,属性包括:集合中的元素个数n,整型指针data存储集合中的元素。

方法有:重载输出,按样例格式输出集合中的元素。

重载+运算符,求集合A和集合B的并集,并返回结果集合。

重载-运算符,求集合B关于集合A的相对补集,并返回结果集合。

重载*运算符,求集合A和集合B的交集,并返回结果集合。

主函数输入集合A、B的数据,计算集合的并、交、相对补。

可根据题目,为CSet类添加需要的成员函数。

输入要求:

测试次数

每组测试数据两行,格式如下:

第一行:集合A的元素个数和元素

第二行:集合B的元素个数和元素

输出要求:

每组测试数据输出如下:

第一行:集合A

第二行:集合B

第三行:A和B的并

第四行:A和B的交

第五行:B关于A的相对补集 与 A关于B的相对补集的并,即(A-B)+(B-A)

每组测试数据间以空行分隔。

输入样例:

2
3 10 20 30
4 10 1 2 3
5 100 2 3 4 -10
6 -34 12 2 4 90 100

输出样例:

A:10 20 30
B:10 1 2 3
A+B:10 20 30 1 2 3
A*B:10
(A-B)+(B-A):20 30 1 2 3

A:100 2 3 4 -10
B:-34 12 2 4 90 100
A+B:100 2 3 4 -10 -34 12 90
A*B:100 2 4
(A-B)+(B-A):3 -10 -34 12 90

代码示例:

#include<iostream>
#include<iomanip>
#include<cstring>
#include<string> 
#include<cmath>
#include<algorithm>
using namespace std;

class Set
{
private:
	int n;
	int* data;
public:
	Set(int nn, int* arr) :n(nn)
	{
		data = new int[n];
		for (int i = 0; i < n; i++)
		{
			data[i] = arr[i];
		}
	}
	Set(Set& rhs) :n(rhs.n)
	{
		for (int i = 0; i < n; i++)
		{
			data[i] = rhs.data[i];
		}
	}
	~Set()
	{
		delete[]data;
	}
	Set operator + (const Set& rhs)
	{
		int count = 0;
		int mark[100] = { 0 };
		for (int i = 0; i < this->n; i++)
		{
			for (int j = 0; j < rhs.n; j++)
			{
				if (this->data[i] == rhs.data[j])
				{
					count++;
					mark[j] = 1;
				}
			}
		}
		int c = this->n + rhs.n - count;
		int* crr = new int[c];
		for (int i = 0; i < this->n; i++)
		{
			crr[i] = this->data[i];
		}
		int cnt = 0;
		for (int i = this->n; i < c; i++)
		{
			while (1)
			{
				if (mark[cnt] == 0)
				{
					crr[i] = rhs.data[cnt];
					cnt++;
					break;
				}
				else
				{
					cnt++;
				}
			}
		}
		Set C(c, crr);
		return C;
	}
	Set operator - (const Set& rhs)
	{
		int count = 0;
		int mark[100] = { 0 };
		for (int i = 0; i < this->n; i++)
		{
			for (int j = 0; j < rhs.n; j++)
			{
				if (this->data[i] == rhs.data[j])
				{
					count++;
					mark[i] = 1;
				}
			}
		}
		int c = this->n - count;
		int* crr = new int[c];
		int cnt = 0;
		for (int i = 0; i < c; i++)
		{
			while (1)
			{
				if (mark[cnt] == 0)
				{
					crr[i] = this->data[cnt];
					cnt++;
					break;
				}
				else
				{
					cnt++;
				}
			}
		}
		Set C(c, crr);
		return C;
	}
	Set operator * (const Set& rhs)
	{
		int count = 0;
		int mark[100] = { 0 };
		for (int i = 0; i < this->n; i++)
		{
			for (int j = 0; j < rhs.n; j++)
			{
				if (this->data[i] == rhs.data[j])
				{
					count++;
					mark[i] = 1;
				}
			}
		}
		int c = count;
		int* crr = new int[c];
		int cnt = 0;
		for (int i = 0; i < c; i++)
		{
			while (1)
			{
				if (mark[cnt] == 1)
				{
					crr[i] = this->data[cnt];
					cnt++;
					break;
				}
				else
				{
					cnt++;
				}
			}
		}
		Set C(c, crr);
		return C;
	}
	friend ostream& operator<<(ostream& out, const Set& rhs);
};

ostream& operator<<(ostream& out, const Set& rhs)
{
	for (int i = 0; i < rhs.n; i++)
	{
		cout << rhs.data[i];
		if (i != rhs.n - 1)
		{
			cout << " ";
		}
		else
		{
			cout << endl;
		}
	}
	return out;
}


int main()
{
	int t;
	cin >> t;
	while (t--)
	{
		int a;
		cin >> a;
		int* arr = new int[a];
		for (int i = 0; i < a; i++)
		{
			cin >> arr[i];
		}
		Set A(a, arr);
		int b;
		cin >> b;
		int* brr = new int[b];
		for (int i = 0; i < b; i++)
		{
			cin >> brr[i];
		}
		Set B(b, brr);

		cout << "A:" << A;
		cout << "B:" << B;

		cout << "A+B:" << A + B;
		cout << "A*B:" << A * B;
		cout << "(A-B)+(B-A):" << (A - B) + (B - A);
		cout << endl;
	}
	return 0;
}

问题考察的运算符重载不难,但是算法较麻烦!

题目九:OOP CString字符串拼接(深拷贝与运算符重载)

题目描述:

定义一个CString类如下:

class CString {

char* s;

int n;

public:

CString(char* const _s=nullptr) : s(nullptr), n(0) {

if (!_s) return;

n = strlen(_s);

s = new char[n + 1]{};

strncpy(s, _s, n);         // 记得 #include <cstring>

}

// 1. 要求重载 '+' 运算符, 实现两个CString对象相加的结果

//   (不能改变原来的两个CString对象)

// ...可以补充其它任意函数...

// (注意:只能添加(成员)函数,不能添加成员变量,不能修改已有定义)

};

// 2. 要求重载 "<<" 运算符以输出CString

主函数如下:(不可修改) 

int main() {

int n;

char input[64 + 1]{}; // ! strlen(s) + 1

cin >> n;

while (n--) {

cin >> input;

CString s1(input);

cin >> input;

CString s2(input);

CString sEmpty; // !

delete new CString(s1 = s1+s2); // !

cout << s1 + sEmpty << endl

 << sEmpty + s2 << endl

 << s1 + s2 << endl

 << endl;

}

return 0;

}

输出要求:

第1行: 1个数字n, 表示测试次数

以下n行: 每行两个字符串, 用空格分隔

输出要求:

参见主函数或样例输出

输入样例:

3
abcd efg
abc defgh
abcde fghi

输出样例:

abcdefg
efg
abcdefgefg

abcdefgh
defgh
abcdefghdefgh

abcdefghi
fghi
abcdefghifghi

代码示例:

#include<iostream>
#include<iomanip>
#include<cstring>
#include<string> 
#include<cmath>
#include<algorithm>
using namespace std;

class String
{
	char* s;
	int n;
public:
	String(char* const _s = nullptr) : s(nullptr), n(0)
	{
		if (!_s) return;
		n = strlen(_s);
		s = new char[n + 1] {};
		strncpy(s, _s, n);
	}
	friend String operator + (const String& s1, const String& s2)//+运算符重载
	{
		char* c = new char[s1.n + s2.n + 1];
		strncpy(c, s1.s, s1.n);//strncpy(arr1, arr2, n),将arr2长度为n复制到arr1中
		strncpy(c + s1.n, s2.s, s2.n);
		c[s1.n + s2.n] = '\0';
		String temp(c);
		return temp;
	}
	friend ostream& operator<<(ostream& out, const String& rhs);
};

ostream& operator <<(ostream& out, const String& rhs)
{
	for (int i = 0; i < rhs.n; i++)
	{
		out << rhs.s[i];
	}
	return out;
}

int main()
{
	int n;
	char input[64 + 1]{};
	cin >> n;
	while (n--)
	{
		cin >> input;
		String s1(input);
		cin >> input;
		String s2(input);

		String sEmpty;
		delete new String(s1 = s1 + s2);

		cout << s1 + sEmpty << endl
			<< sEmpty + s2 << endl
			<< s1 + s2 << endl
			<< endl;
	}
	return 0;
}

记住strncpy的用法!

  • 6
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
定义表示形状的抽象类及相应的派生类,并实现相关操作符重载。 (1)定义表示形状的抽象类Shape: 添加公有成员函数double Area(),用于计算形状面积;定义为纯虚函数; 添加公有成员函数void Show(),用于显示形状信息,定义为纯虚函数; 定义虚的析构函数; 重载比较操作符:==、>和<,用于比较两个形状面积的大小关系,返回值类型为bool,可以定义为成员函数或友元函数。 (2)从形状类Shape派生矩形类Rectangle: 添加double型的保护数据成员:rectWidth和rectHeight,分别表示矩形的宽度和高度; 定义带参构造函数; 重定义公有成员函数Show,打印矩形的宽度和高度,输出格式为“W: 宽度; H: 高度; Area: 面积”; 重定义公有成员函数Area,计算矩形面积。 (3)从形状类Shape派生椭圆类Ellipse: 添加double型的保护数据成员:rectWidth和rectHeight,分别表示椭圆外接矩形的宽度和高度; 定义带参构造函数; 重定义公有成员函数Show,打印椭圆外接矩形的宽度和高度,输出格式为“W: 宽度; H: 高度; Area: 面积”; 重定义公有成员函数Area,计算椭圆面积。 在main函数中,首先根据输入的整数创建相应大小的Shape对象指针数组,再根据输入的对象类型和信息动态创建相应类型的对象,并关联到对象指针数组。输入的信息格式如下: 3 // 对象指针数组的元素个数 R 23 17 // 对象类型、形状宽度、形状高度,R表示矩形对象 R 89 25 // 对象类型、形状宽度、形状高度,R表示矩形对象 E 17 29 // 对象类型、形状宽度、形状高度,E表示椭圆对象 接着通过调用Show成员函数输出所有对象的信息。 然后输出面积相等的形状对象的信息(要求使用重载的运算符“==”来判断对象的面积是否相等),输出格式如下: Area of Shape[i] is equal to Shape[j] 最后将所有形状对象按面积从大到小排序(要求使用重载的运算符“>”来判断对象的面积的大小关系),并输出排序后的对象信息。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

再给艾克三年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值