概述
T1.Purpose of the experiment
Master the basic syntax of operator overloading.
Skillfully use the function with the same name to complete the same basic operation.
T2.Experiment content
[Experiment topic 1]
一。复数类运算符示例程序:
#include
#include
using namespace std;
class Complex{
double Real,Image ;
public :
Complex(double r=0.0, double i=0.0):Real®,Image(i){}
Complex(const Complex &com)
{
Real=com.Real ; Image=com.Image ;
}
void Print()
{cout<<“Real=”<<Real<<’t’<<“Image=”<<Image<<’n’;
}
Complex operator+(Complex); //重载+运算符函数
Complex operator+(double); //重载+运算符函数
Complex operator=(Complex); //重载=运算符函数
Complex operator+=(Complex); //重载+=运算符函数
double abs(void); //求绝对值函数
Complex operator*(Complex); //重载运算符函数
Complex operator/(Complex); //重载/运算符函数
};
Complex Complex::operator+(Complex c)
{//重载+
Complex Temp(Real+c.Real , Image+c.Image) ;
return Temp ;
}
Complex Complex::operator+(double d)
{ //重载+
return Complex(Real+d , Image);
}
Complex Complex::operator+=(Complex c)
{//重载+ =
Complex temp; //为了返回Complex类型的值,使+=可以连续使用
temp.Real=Real+c.Real; temp.Image=Image+c.Image;
Real=temp.Real; Image=temp.Image;
return temp;
}
Complex Complex::operator=(Complex c)
{//重载=
Complex temp; //定义temp为可返回Complex类型值,使=可连续使用
temp.Real=c.Real; temp.Image=c.Image;
Real=temp.Real; Image=temp.Image;
return temp;
}
double Complex::abs(void)
{//求绝对值函数
return sqrt(RealReal+ImageImage);
}
Complex Complex::operator(Complex c)
{//重载*
return Complex(Realc.Real-Imagec.Image ,Realc.Image+c.RealImage);
}
Complex Complex::operator/(Complex c)
{ //重载/
double d=c.Realc.Real+c.Imagec.Image ;
return Complex((Realc.Real+Imagec.Image)/d , (Imagec.Real-Realc.Image)/d) ;
}
int main()
{
Complex c1(1.0,1.0) , c2(2.0,2.0) , c3(4.0,4.0) , c;
double d=0.5 ;
c1.Print();
c=c2+c3 ; c.Print() ;
c+=c1 ; c.Print() ;
c=c+d ; c.Print() ; //可用0.5代替d
c=c3*c2 ; c.Print() ;
c=c3/c1 ; c.Print() ;
cout<<“c3的模为:”<<c3.abs()<<endl ;
c=c3=c2=c1; c.Print(); //连续赋值
c+=c3+=c2+=c1; c.Print(); //连续加赋值
return 0;
}
完成:
1)、如何实现一个整数和一个复数的加法运算(即如:c2=d+c1,其中c1,c2是复数对象,d是一个整数变量)
提示:编写友元函数 friend Complex operator+(int x,Complex &ob);
2)、对示例程序中能够用友元函数实现的运算符,编写友元函数来替换相应的运算符成员函数。
3)、增加重载前置–运算符函数及重载后置–运算符函数,分别用成员函数和友元函数来实现,并测试之。
4)、增加重载的运算符"-"、"-="、"*="、"/=",分别用成员函数和友元函数各做一遍,并测试之。
Experimental procedure
#include <iostream>
#include <cmath>
using namespace std;
class Complex {
double Real, Image;
public:
Complex(double r = 0.0, double i = 0.0) :Real(r), Image(i) {}
Complex(const Complex& com)
{
Real = com.Real; Image = com.Image;
}
void Print()
{
cout << "Real=" << Real << 't' << "Image=" << Image << 'n';
}/*
Complex operator+(Complex); //重载+运算符函数
Complex operator+(double); //重载+运算符函数
Complex operator+=(Complex); //重载+=运算符函数
Complex operator*(Complex); //重载*运算符函数
Complex operator/(Complex); //重载/运算符函数
*/
Complex operator=(Complex); //重载=运算符函数
double abs(void); //求绝对值函数
friend Complex operator+(const Complex&,const Complex &);//重载+运算符非成员函数
friend Complex operator+(double, const Complex&);//重载+运算符非成员函数
friend Complex operator+=(Complex&, const Complex&);//重载+=运算符非成员函数
friend Complex operator*(const Complex&, const Complex&); //重载*运算符非成员函数
friend Complex operator/(const Complex&, const Complex&); //重载/运算符非成员函数
friend Complex operator+(int,const Complex&); /*重载+运算符函数,实现一个整数加一个复数的加法运算*/
Complex operator--(); //重载前置--运算符成员函数
friend Complex operator--(Complex&,int); //重载后置--运算符非成员函数
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-=(Complex&,const Complex&);//重载-=运算符非成员函数
friend Complex operator*=(Complex&,const Complex&);//重载*=运算符非成员函数
friend Complex operator/=(Complex&,const Complex&);//重载/=运算符非成员函数
*/
};
Complex operator+(const Complex&c1,const Complex &c2)
{//重载+
Complex Temp(c1.Real + c2.Real, c1.Image + c2.Image);
return Temp;
}
Complex operator+(double d,const Complex&c)
{ //重载+
return Complex(c.Real + d, c.Image);
}
Complex Complex::operator=(Complex c)
{//重载=
Complex temp; //定义temp为可返回Complex类型值,使=可连续使用
temp.Real = c.Real; temp.Image = c.Image;
Real = temp.Real; Image = temp.Image;
return temp;
}
Complex operator+=(Complex &c1,const Complex &c2)
{//重载+ =
//为了返回Complex类型的值,使+=可以连续使用
c1= c1 + c2;
return c1;
}
double Complex::abs(void)
{//求绝对值函数
return sqrt(Real * Real + Image * Image);
}
Complex operator*(const Complex&c1, const Complex&c2)
{//重载*
return Complex(c1.Real * c2.Real - c1.Image * c2.Image, c1.Real * c2.Image + c2.Real * c1.Image);
}
Complex operator/(const Complex&c1, const Complex&c2)
{ //重载/
double d = c2.Real * c2.Real + c2.Image * c2.Image;
return Complex((c1.Real * c2.Real + c1.Image * c2.Image) / d, (c1.Image * c2.Real - c1.Real * c2.Image) / d);
}
//一个整数和一个复数的加法运算
Complex operator+(int m,const Complex&c)
{
return Complex(c.Real + m, c.Image);
}
//重载前置--运算符成员函数
Complex Complex::operator--() {
Complex c;
Real--; Image--;
c = *this;
return c;
}
//重载后置--运算符非成员函数
Complex operator--(Complex&c1, int) {
Complex c;
c = c1;
c1.Real--;
c1.Image--;
return c;
}
Complex Complex::operator-(const Complex&c) //重载后置-运算符成员函数
{
return Complex(Real - c.Real, Image - c.Image);
}
Complex Complex::operator-=(const Complex&c)//重载-=运算符成员函数
{
*this =(*this)-c;
return *this;
}
Complex Complex::operator*=(const Complex&c)//重载*=运算符成员函数
{
*this = (*this)* c;
return *this;
}
Complex Complex::operator/=(const Complex&c)//重载/=运算符成员函数
{
*this = (*this)/c;
return *this;
}
/*
Complex operator-(const Complex&c1,const Complex&c2)//重载-运算符非成员函数
{
return Complex(c1.Real-c2.Real,c1.Image-c2.Image);
}
Complex operator-=(Complex&c1,const Complex&c2)//重载-=运算符非成员函数
{
c1=c1-c2;
return c1;
}
Complex operator*=(Complex&c1,const Complex&c2)//重载*=运算符非成员函数
{
c1=c1*c2;
return c1;
}
Complex operator/=(Complex&c1,const Complex&c2)//重载/=运算符非成员函数
{
c1=c1/c2;
return c1;
}
*/
int main()
{
Complex c1(1.0, 1.0), c2(2.0, 2.0), c3(4.0, 4.0), c;
double d = 0.5;
c1.Print();
c = c2 + c3; c.Print();
c += c1; c.Print();
c = c + d; c.Print(); //可用0.5代替d
c = c3 * c2; c.Print();
c = c3 / c1; c.Print();
cout << "c3的模为:" << c3.abs() << endl;
c = c3 = c2 = c1; c.Print(); //连续赋值
c += c3 += c2 += c1; c.Print(); //连续加赋值
//测试重载--运算符
cout << endl;
cout << "c:"; c.Print();
cout << "c1:"; c1.Print();
c1=--c;
cout << "c1=--c后nc:"; c.Print();
cout << "c1:"; c1.Print();
c1 = c--;
cout << "c1=c--后nc1:"; c1.Print();
cout << "c: "; c.Print();
//测试-、-=、*=、/=重载运算符;
cout << "c-c1: "; (c - c1).Print();
c -= c1;
cout << "c-=c1后nc:"; c.Print();
c *= c1;
cout << "c*=c1后nc:"; c.Print();
c /= c1;
cout << "c/=c1后nc:"; c.Print();
return 0;
}
Experimental results and analysis
The operation results meet the expectations
Experimental process analysis
We know a C + + class. If the programmer does not define the overloaded function of assignment operator for it, the compiler will implicitly define it, so if we define the overloaded function of global assignment operator again, ambiguity will occur. Even if the compiler allows such a definition technique, it cannot compile at the time of calling.
我们知道一个c++类,程序员如果没有为其定义了赋值操作符重载函数,编译器也会隐式的定义,这样倘若再定义全局赋值运算符重载函数,将会发生二义性。即使编译器允许这样的定义手法,在调用的时候也编译不过。
The assignment (=), subscript ([]), call (()), and member access arrow (- > operators must be members (functions).
赋值(=)、下标([])、调用(())和成员访问箭头(->)运算符必须是成员(函数)。
Secondly, in the process of debugging, I found that when overloading composite operators, we can use operators that have been overloaded to simplify the code. For example, the assignment operator of two objects, the operator of adding and subtracting between two objects, etc.
其次,在调试过程中我发现:当重载复合运算符的过程中,可以利用已经重载好的运算符来达到简化代码的目的。例如两个对象的赋值运算符,两个对象之间相加减的运算符等。
In the function of overloading the - = operator in the picture, the code is simplified only by using the - which operates between two objects already overloaded.
图片中重载-=运算符的函数中,只用利用已经重载好的两个对象之间进行操作的-来简化代码。
Empirical conclusioin
The assignment (=), subscript ([]), call (()), and member access arrow (- > operators must be members (functions).
赋值(=)、下标([])、调用(())和成员访问箭头(->)运算符必须是成员(函数)。
Note: non member versions of overloaded operator functions require the same number of parameters as the number of operands used by operators; member versions require one less parameter because one of the operands is the calling object that is implicitly passed.
注意:非成员版本的重载运算符函数所需的形参数目与运算符使用的操作数数目相同;而成员版本所需的参数数目少一个,因为其中的一个操作数是被隐式地传递的调用对象。
T3.Experiment summary
For the member function version, one operand is implicitly passed through this pointer, and the other operand is explicitly passed as a function parameter; for the friend version, both operands are passed as parameters.
对于成员函数版本来说,一个操作数通过this指针隐式地传递,另一个操作数作为函数参数显式地传递;对于友元版本来说,两个操作数都作为参数传递。
Remember that when you define an operator, you must select one of the formats, not both. Because these two formats match in the same expression, defining these two formats at the same time will be regarded as ambiguous errors, resulting in compilation errors.
So which format is the best? For some operators, as mentioned earlier, member functions are the only legitimate choice. In other cases, there is not much difference between the two formats. Sometimes, depending on the class design, it may be better to use the nonmember function version (especially when defining a type conversion for a class)
记住,在定义运算符时,必须选择其中的一个格式,而不能同时选择这两种格式。因为这两种格式于同一个表达式匹配,同时定义这两种格式将被视为二义性错误,导致编译错误。
那么哪种格式最好呢?对于某些运算符来说(如前所述),成员函数是唯一合法的选择。在其他情况下这两种格式没有太多区别。有时,根据类设计,使用非成员函数版本可能更好(尤其是为类定义类型转换时)
By Suki
2020/5/2
做实验作业是一个很好的记忆C++知识点的方法,在做的过程中,不断地思考代码的简洁性(同时保证可读性),并且可以自己高自由度的不断尝试不一样的方法,不断调试代码,有疑问的地方先去网上查资料,其次才是询问老师或者学长,最后再自己思考总结。这就是成长的过程,忙碌却又不失条理。不断向前那就是正在进步着。
最后
以上就是淡然白羊为你收集整理的运算符重载实验(超基础和干货的代码训练)T1.Purpose of the experimentT2.Experiment contentT3.Experiment summary的全部内容,希望文章能够帮你解决运算符重载实验(超基础和干货的代码训练)T1.Purpose of the experimentT2.Experiment contentT3.Experiment summary所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复