Bootstrap

C++程序设计第十章课后习题答案——运算符重载练习

目录

一、对运算符重载的方法

1、运算符重载函数作为类成员函数

2、运算符重载函数作为友元函数

二、重载流插入运算符“<<”和流提取运算符“>>”

1、重载流插入运算符“<<”

2、重载流提取运算符“>>”

三、不同数据间的类型转换

1、定义一个复数类Complex,重载运算符“+”,使之能用于复数的加法运算。将运算符函数重载为非成员、非友元的普通函数。编程序,求两个复数之和。

2、定义一个复数类Complex,重载运算符“+”、“-”,“*”,“/”,使之能用于复数的加、减、乘、除。运算符重载函数作为Complex类的成员函数。编程序,分别计算两个复数之和、差、积和商。

3、定义一个复数类Complex,重载运算符“+”,使之能用于复数的假发运算。参加运算的两个运算量可以都是类对象,也可以其中一个是整数,顺序任意。编写程序,分别求两个复数之和、整数和复数之和。

4、有两个矩阵a和b,均为2行3列。求两个矩阵之和。重载运算符“+”,使之能用于矩阵相加。

5、有两个矩阵a和b,均为2行3列。求两个矩阵之和。重载运算符“+”,使之能用于矩阵相加,如c=a+b。重载流插入运算符“<<”和流提取运算符“>>”,使之能用于该矩阵的输入和输出。

6、请编写程序,处理一个复数与一个double数相加的运算,结果存放在一个douuble型的变量毒d1中,输出d1的值,再以复数形式输出此值。定义Complex类,在成员函数中包含重载类型转换运算符:operator double(){return real;}

7、定义一个teacher(教师)类和一个student(学生)类,二者有一份数据成员是相同的,例如num,name,sex。编写程序,将一个student对象(学生)转换为teacher(教师)类,只将以上3个相同的数据成员移植过去。可以设想为:一个学生大学毕业了,留校担任教师,他原有的部分数据对现在的教师身份来说仍然是有用的,应当保留并成为其教师的数据的一部分。


一、对运算符重载的方法

1、运算符重载函数作为类成员函数

  • 定义类 operator+(定义类 &);
  • 当c1+c2编译器解释为c1.operator+(c2)
  • 如果将运算符重载作为成员函数,它可以通过this指针自由地地址访问本类的数据成员,因此可以少写一个函数的参数。

2、运算符重载函数作为友元函数

  • friend 定义类 operator+(定义类 &,定义类 &);
  • 当c1+c2编译器解释为operator+(c1,c2)
  • 双目运算符重载为友元函数时,由于友元函数不是该类的成员函数,因此在函数的形参列表中必须有两个参数,不能省略。

二、重载流插入运算符“<<”和流提取运算符“>>”

1、重载流插入运算符“<<”

  • friend istream& operator>>(istream&,Arr&);

2、重载流提取运算符“>>”

  • friend ostream& operator<<(ostream&,Arr&);

三、不同数据间的类型转换

1、转换构造函数

  • Complex(double r){real=r;imag=0;}
  • 转换构造函数只能有一个参数。如果有多个参数的,它就不是转换构造函数。

2、类型转换函数

  • operator 类型名(){实现转换的语句}
  • 类型转换函数只能作为成员函数,因为转换的主体是本类的对象。不能作为友元函数或普通函数。

1、定义一个复数类Complex,重载运算符“+”,使之能用于复数的加法运算。将运算符函数重载为非成员、非友元的普通函数。编程序,求两个复数之和。

#include <iostream>
using namespace std;
//习题 1
class Complex{
public:
    Complex(){real=0;imag=0;}
    Complex(double r,double i){real=r;imag=i;}
    double get_real(){return real;}
    double get_imag(){return imag;}
    void display();
private:
    double real;
    double imag;
};


void Complex::display() {
    cout<<"("<<real<<","<<imag<<"i)"<<endl;
}
Complex operator + (Complex &c1,Complex &c2)
{
    return Complex(c1.get_real()+c2.get_real(),c1.get_imag()+c2.get_imag());
}

int main(){
    Complex c1(3,1),c2(2,-7),c3;
    cout<<"c1=";c1.display();
    cout<<"c2=";c2.display();
    cout<<"c1+c2=";c3.display();
}

2、定义一个复数类Complex,重载运算符“+”、“-”,“*”,“/”,使之能用于复数的加、减、乘、除。运算符重载函数作为Complex类的成员函数。编程序,分别计算两个复数之和、差、积和商。

//习题 2
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) {
    return Complex(real+c2.real,imag+c2.imag);
}
Complex Complex::operator-(Complex &c2) {
    return Complex(real-c2.real,imag-c2.imag);
}
Complex Complex::operator*(Complex &c2) {
    return Complex(real*c2.real-imag*c2.imag,imag*c2.real+real*c2.imag);
}
Complex Complex::operator/(Complex &c2) {
    return Complex((real*c2.real+imag*c2.imag)/(c2.real*c2.real+c2.imag*c2.imag),(imag*c2.real+real*c2.imag)/(c2.real*c2.real+c2.imag*c2.imag));
}

void Complex ::display() {
    cout<<"("<<real<<","<<imag<<"i)"<<endl;
}

3、定义一个复数类Complex,重载运算符“+”,使之能用于复数的假发运算。参加运算的两个运算量可以都是类对象,也可以其中一个是整数,顺序任意。编写程序,分别求两个复数之和、整数和复数之和。

//习题 3
class Complex{
public:
    Complex(){real=0;imag=0;}
    Complex(double r,double  i){real=r;imag=i;}
    friend Complex operator+(Complex &c1,Complex &c2);
    friend Complex operator+(int &i,Complex &c1);
    friend Complex operator+(Complex &c1,int &i);
    void display();
private:
    double real;
    double imag;
};

Complex operator+(Complex &c1,Complex &c2){
    return Complex(c1.real+c2.real,c1.imag+c2.imag);
}
Complex operator+(Complex &c1,int &i){
    return Complex(c1.real+i,c1.imag);
}
Complex operator+(int &i,Complex&c1){
    return Complex(i+c1.real,c1.imag);
}
void Complex::display() {
    cout<<"("<<real<<","<<imag<<"i)"<<endl;
}

int main(){
    Complex c1(2,3),c2(2,9),c3;
    int i=2;
    cout<<"c1=";c1.display();
    cout<<"c2=";c2.display();
    c3=c1+c2;
    cout<<"c1+c2=";c3.display();
    c3=i+c1;
    cout<<"i+c1=";c3.display();
    c3=c1+i;
    cout<<"c1+i=";c3.display();
}

4、有两个矩阵a和b,均为2行3列。求两个矩阵之和。重载运算符“+”,使之能用于矩阵相加。

//习题 4
#include <iomanip>
class Arr{
public:
    Arr();
    friend Arr operator+(Arr &a1,Arr &a2);
    void inp();
    void out();
private:
    int arr[2][3];
};
Arr::Arr() {
    for (int i = 0; i < 2; ++i)
        for (int j = 0; j < 3; ++j)
            arr[i][j]=0;
}
Arr operator+(Arr&a1,Arr&a2){
    Arr a3;
    for (int i = 0; i < 2; ++i)
        for (int j = 0; j < 3; ++j)
            a3.arr[i][j]=a1.arr[i][j]+a2.arr[i][j];
    return a3;
}
void Arr::inp() {
    for (int i = 0; i < 2; ++i)
        for (int j = 0; j < 3; ++j)
            cin>>arr[i][j];
}
void Arr::out() {
    for (int i = 0; i < 2; ++i){
        for (int j = 0; j < 3; ++j)
            cout << setw(4) << arr[i][j];
        cout<<endl;
    }
}

int main(){
    Arr a1 ,a2, a3;
    a1.inp();
    a2.inp();
    a3=a1+a2;
    a3.out();

}
/*

1 2 3 4 5 6
1 2 3 4 5 6
   2   4   6
   8  10  12
*/

5、有两个矩阵a和b,均为2行3列。求两个矩阵之和。重载运算符“+”,使之能用于矩阵相加,如c=a+b。重载流插入运算符“<<”和流提取运算符“>>”,使之能用于该矩阵的输入和输出。

//习题 5
#include <iomanip>
using namespace std;
class Arr {
public :
    friend ostream& operator<<(ostream&,Arr&);
    friend istream& operator>>(istream&,Arr&);
    friend Arr operator + (Arr & c1,Arr & c2);
    Arr();
private :
    int Q[2][3];
};
Arr::Arr() {
    for(int i=0; i<2; i++)
        for(int j=0; j<3; j++)
            Q[i][j]=0;
}
ostream & operator <<(ostream & output,Arr& a) {
    for (int i=0; i<2; i++) {
        for (int j=0; j<3; j++)
            output<<setw(4)<<a.Q[i][j];
        output<<endl;
    }
    return output;
}
istream & operator >>(istream & input,Arr& a) {
    for (int i=0; i<2; i++)
        for (int j=0; j<3; j++)
            input>>a.Q[i][j];
    return input;
}
Arr operator +(Arr & a1,Arr & a2) {
    Arr a3;
    for (int i=0; i<2; i++)
        for (int j=0; j<3; j++)
            a3.Q[i][j]=a1.Q[i][j]+a2.Q[i][j];
    return a3;
}
int main() {
    Arr a1,a2,a3;
    cin>>a1>>a2;
    a3=a1+a2;
    cout<<a3;
    return 0;
}

6、请编写程序,处理一个复数与一个double数相加的运算,结果存放在一个douuble型的变量毒d1中,输出d1的值,再以复数形式输出此值。定义Complex类,在成员函数中包含重载类型转换运算符:operator double(){return real;}

//习题 6
class Complex{
public:
    Complex(){real=0;imag=0;}
    Complex(double r,double i){real=r;imag=i;}
    Complex(double d1){real=d1;imag=0;}
    operator double (){return real;}
    void out(){cout<<real<<"+"<<imag<<"i";}
private:
    double real;
    double imag;
};

int main(){
    Complex c1(2,3),c2;
    double d1;
    d1=2.5+c1;
    cout<<d1<<endl;
    c2=Complex(d1);
    c2.out();
    return 0;
}

7、定义一个teacher(教师)类和一个student(学生)类,二者有一份数据成员是相同的,例如num,name,sex。编写程序,将一个student对象(学生)转换为teacher(教师)类,只将以上3个相同的数据成员移植过去。可以设想为:一个学生大学毕业了,留校担任教师,他原有的部分数据对现在的教师身份来说仍然是有用的,应当保留并成为其教师的数据的一部分。

//习题 7
class Student{
public:
    Student(){num=10;name="王";sex='M';}
    void display(){
        cout<<num<<endl;
        cout<<name<<endl;
        cout<<sex<<endl;
    }
private:
    int num;
    string name;
    char sex;
};
class Teacher:public Student{};

int main(){
    Teacher t1;
    t1.display();
}

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;