1. 定义一个复数类Complex,重载运算符"+",使之能用于复数的加法运算。将运算符函数重载为非成员、非友元的普通函数。编写程序,求两个复数之和
#include <iostream>
using namespace std;
class Complex
{
public:
Complex() { real = 0; image = 0; }
Complex(double r, double i) { real = r, image = i; }
double get_real(); //声明get_real函数
double get_image(); //声明get_image函数
void display();
private:
double real;
double image;
};
double Complex::get_real() //取数据成员real(实部)的值
{return real; }
double Complex::get_image() //取数据成员image(虚部)的值
{ return image; }
void Complex::display()
{ cout << "(" << real << "," << image << "i)" << endl; }
Complex operator+(Complex& c1, Complex& c2)
{ return Complex(c1.get_real() + c2.get_real(), c1.get_image() + c2.get_image()); }
int main() {
Complex c1(3, 4), c2(5, -10), c3;
c3 = c1 + c2;
cout << "c3=";
c3.display();
return 0;
}
//运行结果:c3=(8,-6i)
程序分析:
- 运算符重载函数既不是类Complex的成员函数,也不是类Complex的友元函数,而是一个普通函数。
- 由于运算符重载函数operator+是非成员和非友元的普通函数,因此它不能直接引用Complex类中的私有成员
结论:一般不把运算符函数重载为非成员和非友元的普通函数
2. 定义一个复数类Complex,重载运算符"+","-","*","/",使之能用于复数的加、减、乘、除。运算符重载函数作为Complex类的成员函数。编写程序,分别求两个复数之和、查、积和商
如果有两个复数:m=a+bi,n=c+di。复数的加、减、乘、除的公式如下:
- 复数加法: m + n = a + b i + c + d i = ( a + c ) + ( b + d ) i m+n=a+bi+c+di=(a+c)+(b+d)i m+n=a+bi+c+di=(a+c)+(b+d)i
- 复数减法: m − n = a + b i − c − d i = ( a − c ) + ( b − d ) i m-n=a+bi-c-di=(a-c)+(b-d)i m−n=a+bi−c−di=(a−c)+(b−d)i
- 复数乘法: m × n = ( a + b i ) ( c + d i ) = a c + b c i + a d i + b d i ² = ( a c − b d ) + ( b c + a d ) i m×n=(a+bi)(c+di)=ac+bci+adi+bdi²=(ac-bd)+(bc+ad)i m×n=(a+bi)(c+di)=ac+bci+adi+bdi²=(ac−bd)+(bc+ad)i
- 复数除法: m n = ( a + b i ) ( c − d i ) ( c + d i ) ( c − d i ) = a c + b c i − a d i − b d i ² c ² + d ² = ( a c + b d ) + ( b c − a d ) i c ² + d ² = a c + b d c ² + d ² + b c − a d c ² + d ² i \frac{m}{n}=\frac{(a+bi)(c-di)}{(c+di)(c-di)}=\frac{ac+bci-adi-bdi²}{c²+d²}=\frac{(ac+bd)+(bc-ad)i}{c²+d²}=\frac{ac+bd}{c²+d²}+\frac{bc-ad}{c²+d²}i nm=(c+di)(c−di)(a+bi)(c−di)=c²+d²ac+bci−adi−bdi²=c²+d²(ac+bd)+(bc−ad)i=c²+d²ac+bd+c²+d²bc−adi
#include<iostream>
using namespace std;
class Complex
{
public:
Complex() { real = 0; imag = 0; }
Complex(double r, double i) { real = r; imag = i; }
Complex operator+(Complex& c2);
Complex operator-(Complex& c2);
Complex operator*(Complex& c2);
Complex operator/(Complex& c2);
void display();
private:
double real;
double imag;
};
Complex Complex::operator+(Complex& c2) //重载运算符"+"
{
Complex c;
c.real = real + c2.real; //计算实部
c.imag = imag + c2.imag; //计算虚部
return c;
}
Complex Complex::operator-(Complex& c2) //重载运算符"-"
{
Complex c;
c.real = real - c2.real; //计算实部
c.imag = imag - c2.imag; //计算虚部
return c;
}
Complex Complex::operator*(Complex& c2) //重载运算符"*"
{
Complex c;
c.real = real * c2.real - imag * c2.imag; //计算实部
c.imag = imag * c2.real + real * c2.imag; //计算虚部
return c;
}
Complex Complex::operator/(Complex& c2) //重载运算符"/"
{
Complex c;
c.real = (real * c2.real + imag * c2.imag) / (c2.real * c2.real + c2.imag * c2.imag); //计算实部
c.imag = (imag * c2.real - real * c2.imag) / (c2.real * c2.real + c2.imag * c2.imag); //计算虚部
return c;
}
void Complex::display()
{
cout << "(" << real << "," << imag << "i)" << endl; //输出复数
}
int main()
{
Complex c1(3, 4), c2(5, -10), c3;
c3 = c1 + c2;
cout << "c1+c2=";
c3.display();
c3 = c1 - c2;
cout << "c1+c2=";
c3.display();
c3 = c1 * c2;
cout << "c1*c2=";
c3.display();
c3 = c1 / c2;
cout << "c1/c2=";
c3.display();
return 0;
}
运行结果:
3. 定义一个复数类Complex,重载运算符"+",使之能用于复数的加法运算。参加运算的两个运算量可以都是类对象,也可以其中有一个是整数,顺序任意。编写程序,分别求出两个复数之和、整数和复数之和
#include<iostream>
using namespace std;
class Complex
{
public:
Complex() { real = 0; imag = 0; }
Complex(double r, double i) { real = r; imag = i; }
Complex operator+(Complex& c2); //运算符重载为成员函数
Complex operator+(int& i); //运算符重载为成员函数
friend Complex operator+(int&, Complex&); //运算符重载为友元函数
void display();
private:
double real;
double imag;
};
Complex Complex::operator+(Complex& c) //定义成员运算符函数
{
return Complex(real + c.real, imag + c.imag);
}
Complex Complex::operator+(int& i) //定义成员运算符函数
{
return Complex(real + i, imag);
}
void Complex::display()
{
cout << "(" << real << "," << imag << "i)" << endl; //输出复数
}
Complex operator+(int& i, Complex & c)
{
return Complex(i + c.real, c.imag);
}
int main()
{
Complex c1(3, 4), c2(5, -10), c3;
int i = 5;
c3 = c1 + c2;
cout << "c1+c2=";
c3.display();
c3 = i + c1;;
cout << "i+c1=";
c3.display();
c3 = c1 + i;
cout << "c1+i=";
c3.display();
return 0;
}
程序分析:
- 由于前两个重载函数的第一个参数为类对象,所以将它们作为类的成员函数,函数的第一个参数也可以省略。第3个重载函数的第一个参数为int型,不是类对象,不能作为类的成员函数,只能作为友元函数,函数的两个参数不能省略。
- 也可以将以上3个运算符函数都重载为友元函数,这时3个运算符函数都有两个参数,不能省略。注意在友元函数中引用数据成员必须用对象名。
运行结果:
4. 有两个矩阵a和b,均为2行3列。求两个矩阵之和。重载运算符"+",使之能用于两个矩阵相加。
#include<iostream>
using namespace std;
class Matrix
{
public:
Matrix(); //默认构造函数
friend Matrix operator+(Matrix&, Matrix&); //重载运算符"+"
void input(); //输入数据函数
void display(); //输出数据函数
private:
int mat[2][3];
};
Matrix::Matrix() //定义构造函数
{
for (int i = 0; i < 2; i++)
for (int j = 0; j < 3; j++)
mat[i][j] = 0;
}
Matrix operator+(Matrix& a, Matrix& b) //定义重载运算符+函数
{
Matrix c;
for (int i = 0; i < 2; i++)
for (int j = 0; j < 3; j++)
c.mat[i][j] = a.mat[i][j] + b.mat[i][j];
return c;
}
void Matrix::input() //定义输入数据函数
{
cout << "input value of matrix:";
for (int i = 0; i < 2; i++)
for (int j = 0; j < 3; j++)
cin >> mat[i][j];
}
void Matrix::display()
{
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
{
cout << mat[i][j] << " ";
}
cout << endl;
}
}
int main()
{
Matrix a, b, c;
a.input();
b.input();
cout << endl << "Matrix a:" << endl;
a.display();
cout << endl << "Matrix b:" << endl;
b.display();
c = a + b;
cout << endl << "Matrix c = Matrix a + Marix b:" << endl;
c.display();
return 0;
}
运行结果:
5. 在上题的基础上,重载流插入运算符"<<“和流提取运算符”>>",使之能用于该矩阵的输入和输出
#include<iostream>
using namespace std;
class Matrix
{
public:
Matrix(); //默认构造函数
friend Matrix operator+(Matrix&, Matrix&); //重载运算符"+"的函数声明
friend ostream& operator<<(ostream&, Matrix&); //重载运算符"<<"的函数声明
friend istream& operator>>(istream&, Matrix&); //重载运算符">>"的函数声明
private:
int mat[2][3];
};
Matrix::Matrix() //定义构造函数
{
for (int i = 0; i < 2; i++)
for (int j = 0; j < 3; j++)
mat[i][j] = 0;
}
Matrix operator+(Matrix& a, Matrix& b) //定义运算符"+"的重载函数
{
Matrix c;
for (int i = 0; i < 2; i++)
for (int j = 0; j < 3; j++)
c.mat[i][j] = a.mat[i][j] + b.mat[i][j];
return c;
}
istream& operator>>(istream& in, Matrix& m)
{
cout << "input value of matrix:";
for (int i = 0; i < 2; i++)
for (int j = 0; j < 3; j++)
in >> m.mat[i][j];
return in;
}
ostream& operator<<(ostream& out, Matrix& m)
{
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
{
out<< m.mat[i][j]<<" ";
}
out << endl;
}
return out;
}
int main()
{
Matrix a, b, c;
cin >> a;
cin >> b;
cout << endl << "Matrix a:" << endl << a << endl;
cout << endl << "Matrix b:" << endl << b << endl;
c = a + b;
cout << endl << "Matrix c = Matrix a + Marix b:" << endl << c << endl;
return 0;
}
6. 请编写程序,处理一个复数域一个double数相加的运算,结果存放在一个double型的变量d1中,输出d1的值,再以复数形式输出此值。定义Complex(复数)类,在成员函数中包含重载类型转换运算符:operator double(){return real;}
#include<iostream>
using namespace std;
class Complex
{
public:
Complex() { real = 0; imag = 0; } //默认构造函数,无形参
Complex(double r) { real = r; imag = 0; } //转换构造函数,一个形参
Complex(double r, double i) { real = r; imag = i; } //实现初始化的构造函数,两个形参
operator double() { return real; } //重载类型转换运算符
void display();
private:
double real;
double imag;
};
void Complex::display()
{
cout << "(" << real << "," << imag << ")" << endl;
}
int main()
{
Complex c1(3, 4), c2;
double d1;
d1 = 2.5 + c1; //将c1转换为double型数,与2.5相加,结果为double型数
cout << "d1=" << d1 << endl; //输出double型变量d1的值
c2 = Complex(d1); //将d1再转换为复数
cout << "c2=";
c2.display(); //输出复数c2
return 0;
}
//运行结果:
d1=5.5
c2=(5.5,0)
程序分析:
- 在处理表达式"2.5+c1"时,由于二者的类型不同,如果没有重载强制类型转换运算符,二者是不能相加的。由于在Complex类中已重载了类型转换运算符double,在程序编译时,编译系统找到了此函数,并将Complex类对象c1(复数)转换成一个double型数据3.0,然后将2.5与3.0相加,得5.5。用cout语句输出d1的值。
- 如果想将d1以复数形式表示,可以利用转换构造函数将d1转换为Complex类对象,即Complex(d1)。主函数最后两行就是为了处理这个问题。
如果将程序中的Complex类的公用部分改为:
class Complex
{
public:
Complex() { real = 0; imag = 0; }
Complex(double r) { real = r; imag = 0; } //转换构造函数
Complex(double r, double i) { real = r; imag = i; }
operator double() { return real; } //重载类型转换运算符
friend Complex operator+(Complex c1, Complex c2);
void display();
private:
double real;
double imag;
};
程序分析:
- 如果想把"2.5+c1"处理为两个复数相加,而不是按两个double数相加,程序在编译时出错,原因是出现二义性。一种理解是:调用转换构造函数,把2.5变成Complex类对象,然后调用运算符"+“重载函数,与c1进行复数相加。另一种理解是:调用类型转换函数,把c1转换为double型数,然后与2.5进行相加。系统无法判定,这二者是矛盾的。如果要使用类型转换函数,就应当删去运算符”+"重载函数。
- 转换构造函数是将double型数据转化为Complex类对象,类型转换函数是将Complex类对象转换成一个double型数据。
7. 定义一个Teacher(教师)类和一个Student(学生)类,二者有一部分数据成员是相同的,例如num(号码),name(姓名),sex(性别)。编写程序,将一个Student对象(学生)转换为Teacher(教师)类,只将以上3个相同的数据成员移植过去。可以设想为:一位学生大学毕业了,留校担任教师,他原有的部分数据对现在的教师身份来说仍然是有用的,应当保留并成为其教师数据的一部分。
#include<iostream>
using namespace std;
class Student //定义学生类
{
public:
Student(int, char[], char, float); //构造函数声明
int get_num() { return num; } //返回num的值
char* get_name() { return name; } //返回name的值
char get_sex() { return sex; } //返回sex的值
void display()
{
cout << "num:" << num << "\nname:" << name << "\nsex:" << sex << "\nscore:" << score << "\n\n";
}
private:
int num;
char name[20];
char sex;
float score; //成绩
};
Student::Student(int n, char nam[], char s, float sco) //定义Student构造函数
{
num = n;
strcpy(name, nam);
sex = s;
score = sco;
};
class Teacher //定义教师类
{
public:
Teacher(){} //默认构造函数
Teacher(Student&); //转换构造函数
Teacher(int n, char nam[], char sex, float pay); //构造函数重载
void display();
private:
int num;
char name[20];
char sex;
float pay; //工资
};
Teacher::Teacher(int n, char nam[], char s, float p) //定义Teacher构造函数
{
num = n;
strcpy(name, nam);
sex = s;
pay = p;
}
Teacher::Teacher(Student& stud) //定义转换构造函数
{
num = stud.get_num(); //将Student类对象的num成员转换为Teacher类对象的num
strcpy(name, stud.get_name());
sex = stud.get_sex();
pay = 1500; //假定试用期临时工资一律为1500元
}
void Teacher::display()
{
cout<<"num:" << num << "\nname:" << name << "\nsex:" << sex << "\npay:" << pay << "\n\n";
}
int main()
{
Teacher teacher1(10001, "Li", 'f', 1234.5), teacher2;
Student student1(20010, "Wang", 'm', 89.5);
cout << "student1:" << endl;
student1.display(); //输出学生student1的信息
teacher2 = Teacher(student1); //将student1转换为Teacher类
cout << "teacher2:" << endl;
teacher2.display(); //输出教师teacher2的信息
return 0;
}
运行结果