The design and experiment of basic operations and operator overloading such as C language/C++ (3/5)

1. Purpose of the experiment:

1. Understand the characteristics and ideas of object-oriented programming, understand the encapsulation and information hiding of classes.

2. Master the definition and function of classes and objects, and use them proficiently.

3. Master the definition of member functions of classes, and be proficient in defining and applying member functions of classes.

4. Master the references of object members, and skillfully apply the references of object members.

5. To master the constructor and destructor, skillful application is required.

2. Experimental content

  1. Read the program, analyze its output after execution, and test and verify it on the computer.

code:

#include <iostream.h>

#include <string.h>

class MyClal

{  char  *str;

  public:

      MyClal(char *s);

      MyClal()

      {  cout<<"Destructor:Destroying=>"<<str<<"\n";

         delete str; }

      void print(){cout<<"------printed by=>"<<str<<endl;}};

MyClal::MyClal(char *s)

{   cout<<"Constructor:Initializing=>"<<s<<"\n";

    str=new char[strlen(s)+1];

    strcpy(str,s);}

MyClal IO("Global IO");

void main()

{   IO.print();

    MyClal I1("function_Local I1");

    int cond=2;

    I1.print();

    while(cond)

    {  cout<<"In block.\n";

       MyClal I2("Block_Local I2");

       I2.print();

       static MyClal I3("Static I3");

       cond--;  }

    cout<<"Exited block.\n";}

程序测试及运行结果:

  1. 编程实现:设计一个职工类Person,一个系有若干个职工,按职务分为系主任、室主任和职工,给出他们之间的领导关系。

程序代码:

#include<iostream.h>
#include<stdio.h>
#include<string.h>
class Person    //定义person类
{

char name[10];  //分别定义个char型的 name 和prof数组用储存姓名和职务
char prof[10];
Person *leader;
public:
Person(){strcpy(name,"\0");

}
Person(char n[],char p[])
{

strcpy(name,n);
strcpy(prof,p);
leader=new Person;//jia}
void setleader(Person &p){leader=&p;} // 将对象引用作为参数
char *getname(){ return name;}//返回职工姓名
Person *getleader()
{

return leader;//返回领导者姓名

}
void disp()   //依次输出姓名和职务的调用函数
{

printf("%10s %10s%",name,prof);

}};
void main()
{

Person p[]={Person("王华","室主任"),Person("李明","职工"),
Person("陈强","系主任"),Person("章城","职工"),
Person("张伟","室主任"),Person("许源","职工")

};
p[0].setleader(p[2]);
p[1].setleader(p[0]);
p[3].setleader(p[4]);
p[4].setleader(p[2]);
p[5].setleader(p[4]);//进行员工的和领导的排序
printf("      姓名     职务     领导姓名\n");
printf("------------------------------\n");
for(int i=0;i<6;i++)
{

p[i].disp();

//循环 输出姓名和职务
printf("%10s\n",(p[i].getleader())->getname());

//循环输出领导姓名

}}

程序测试及运行结果:

  1. 编程实现:定义如下形式的类模板myTmplt,其实例化后的类对象的数据成员由三元组(x,y,z)所构成,而数据的类型则为可变化的类型T(并假设T为可比较大小的某种类型)。模板中还设有其他几个成员函数,用于对三元组数据进行指定处理。

程序代码:

#include<iostream>

using namespace std;

template <class T>class

myTmplt

{

    T x,y,z;

    public: 

      myTmplt(T x0,T y0,T z0){x=x0;y=y0;z=z0;}    //构造函数

      T max()        //求三个数据中份成员的最大者

{

    int d;

    if(x>y)

       d=(x>y)?x:y;

    else

       d=(y>z)?y:z;//排序语句

    return d;

};

      bool order()   //三个数据成员从小到大是否有序

      { return(x<y && x<y && x<y)? true:false;  };

      void print()              //屏幕显示 输出

      {  cout<<x<<" "<<y<<" "<<z<<endl;};

};

int main()

{  myTmplt<int>s1(1,2,5);

   s1.print();

   cout<<"s1.max="<<s1.max()<<endl;

if(s1.order())

    cout<<"s1.order()=>OK!"<<endl;

myTmplt<char>s2('A','t','f');

s2.print();

   cout<<"s2.max="<<s2.max()<<endl;

if(s2.order())

    cout<<"s2.order()=>OK!"<<endl;

}

程序测试及运行结果:

  1. 编程实现:有一个学生类student,包括学生姓名、成绩,设计一个友元函数,输出成绩对应的等级:≥90,优;80~89,中;70~79,中;60~69,及格;<60,不及格。

程序代码:

#include<iostream>//头文件

#include<cstring>

#include<iomanip>

using namespace std;//命名空间

class student//定义student类

{

char name[10];//定义存储姓名的数组

int deg;

char level[7];//储存成绩的数组

public:

student(char na[],int d)

{

strcpy(name,na);//字符串复制

deg=d;//私有数据

}

char *getname(){ return name;}

friend void trans(student &s)//定义友元函数

{//等级判断

if(s.deg>=90)

strcpy(s.level,"优");

else if(s.deg>=80)

strcpy(s.level,"良");

else if(s.deg>=70)

strcpy(s.level,"中");

else if(s.deg>=60)

strcpy(s.level,"及格");

else

strcpy(s.level,"不及格");

}

int disp( )

{

cout<<setw(10)<<name<<setw(6)<<deg<<setw(8)<<level<<endl;

}};

int main( )

{

student st[]={student("王华",78),student("李明",92),student("张伟",62),student("孙强",88)};

cout<<"输出结果:"<<endl;

cout<<setw(10)<<"姓名"<<setw(6)<<"成绩"<<setw(8)<<"等级"<<endl;

for (int i=1;i<4;i++)//循环输出

{  trans(st[i]);

       st[i].disp();

    }

return 0;}

程序测试及运行结果:

  1. 编程实现:定义一个复数类Complex,重载运算符“+”、“-”、“*”、“/”,使之能用于复数的加减乘除运算。编写程序,分别求两个复数的和、差、积和商。

程序代码:

#include<iostream>//头文件

using namespace std;//命名空间

class Complex//定义复数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;

c.imag=imag*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;}

程序测试及运行结果:

  1. 编写程序:定义一个字符串类String,用来存放不定长的字符串,重载运算符“==”、“<”和“>”,用于两个字符串的等于、小于和大于的比较运算。

程序代码:

#include<iostream>

#include<cstring>

using namespace std;

class String

{public:

       String()//定义默认构造函数

       {   p=NULL;}

       String(const char *str);//声明构造函数

       void display();//声明输出p所指向的字符串函数

       friend bool operator>(String &string1,String &string2);//声明运算符重载函数为友元函数

       friend bool operator<(String &string1,String &string2);//声明运算符重载函数为友元函数

       friend bool operator==(String &string1,String &string2);//声明运算符重载函数为友元函数

    private:

       const char *p;//字符型指针,用于指向字符串 };

String::String(const char *str)//定义构造函数

{p=str;//使p指向形参字符串 }

void String::display()//定义输出p所指向的字符串函数

{   cout<<p;}

bool operator>(String &string1,String &string2)//对运算符">"重载

{if(strcmp(string1.p,string2.p)>0)

       return true;

    else

        return false;}

bool operator<(String &string1,String &string2)//对运算符"<"重载

{if(strcmp(string1.p,string2.p)<0)

        return true;

    else

       return false;}

bool operator==(String &string1,String &string2)//对运算符"=="重载

{if(strcmp(string1.p,string2.p)==0)

       return true;

    else

       return false;}

void compare(String &string1,String &string2)

{if(operator>(string1,string2)==1)

    {string1.display();

       cout<<">";

       string2.display();

       cout<<endl;}

    else if(operator<(string1,string2)==1)

    {string1.display();

       cout<<"<";

       string2.display();

       cout<<endl;}

    else if(operator==(string1,string2)==1)

    {string1.display();

       cout<<"==";

       string2.display();

       cout<<endl;}}

int main()

{String string1("Hello"),string2("Book"),string3("Computer"),string4("Hello");//定义对象

    compare(string1,string2);

    compare(string2,string3);

    compare(string1,string4);

    return 0;

}  

程序测试及运行结果:

  1. 编写程序。定义一个二维方阵类matrix。通过重载二元运算符“+”、“-”、“*”和一元运算符“~”,来实现矩阵加、矩阵减、矩阵乘以及矩阵转置。

程序代码:

#include<iostream>//头文件

using namespace std;//命名空间

class Matrix

{friend ostream& operator<<(ostream& out, Matrix& M); //重载<<运算符

friend istream& operator>>(istream& in,Matrix& M); //重载>>运算符

public:

Matrix(int r,int c);

Matrix operator+(Matrix &M) ;

Matrix operator-(Matrix &M);

Matrix operator*(Matrix &M);

int GetCounts()

{return rows*cols;}

private:

int rows, cols; //定义矩阵的行数rows,列数cols

double *m; //矩阵中实际(物理)按行存放的元素};

Matrix::Matrix(int r,int c)

{rows=r,cols=c;

m=new double[rows*cols];}

istream& operator>>(istream& in,Matrix& M) //输入流重载

{int i;

for(i=0;i<M.rows*M.cols;i++)

{in>>*(M.m+i);}

return in;}

ostream& operator<<(ostream& out,Matrix& M) //输出流重载

{int i,j=0;

for(i=0; i<M.rows*M.cols; i++)

{if(j==M.cols) j=0,out<<endl;

out<<" "<<*(M.m+i);

j++;

}return out;

}Matrix Matrix::operator+(Matrix &M)

{int i;

Matrix tempM(rows,cols);

for(i=0;i<rows*cols;i++)

*(tempM.m+i)=*(m+i)+*(M.m+i);

return tempM;}

Matrix Matrix::operator-(Matrix &M)

{int i;

Matrix tempM(rows,cols);

for(i=0;i<rows*cols;i++)

*(tempM.m+i)=*(m+i)-*(M.m+i);

return tempM;

}Matrix Matrix::operator*(Matrix &M)

{int i,j,t,k=0;

Matrix tempM(rows,cols);

for(i=0; i<rows*cols; i+=cols)

for(j=0;j<cols;j++)

for(t=0,*(tempM.m+k)=0;t<cols;t++)

*(tempM.m+k)=*(tempM. m+k)+*(m+i+t)**(M.m+j+t*rows);

}int main()

{Matrix A(3,3);

Matrix B(3,3);

Matrix C(3,3);

cout<< "输入第一个矩阵的"<<A.GetCounts()<<"个数:"<<endl;cin>>A;

cout<<"输入第二个矩阵的"<<B.GetCounts()<<"个数:"<<endl;cin>>B;

C=A+B;

cout<<endl<<"矩阵之和:"<<endl;

cout<<C<<endl;

cout<<endl<<"矩阵之差:"<<endl;

C=A-B;

cout<<C<<endl;

C=A*B;

cout<<endl<<"矩阵之积:"<<endl;

cout<<C<<endl<<endl;}

程序测试及运行结果:

分析与讨论:

  1. 对象的赋值和复制有什么区别?

答:赋值是必须先定义一个对象,然后用一个已有值的对象去给这个对象赋值,而对象的复制是从无到有的建立一个对象并赋值。

  1. 复制构造函数的作用是什么?

答:复制构造函数中,可以对数据成员进行其他处理,表示我引用了构造函数,在复制构造函数中,进一步操作,此时构造函数不变。

  1. 如果A类是B类的友元,B类是C类的友元,那么A类是C类的友元吗?

答:友元的关系是不能传递的,所以类A不是类C的友元。

4、使用静态数据成员有什么特点和优势?

答:静态成员的特点:不管类创建多少个对象,其静态成员在内存中只保留一份副本,这个副本为该类的所有对象所共享。
静态数据成员优势:不存在与程序中其它全局名字冲突的可能性且可以实现信息隐藏。

  1. 双目运算符如何对类的对象进行运算?

答:利用友元函数重载流操作符​​​​或者定义在类外部,使用类的成员函数暴露对类成员的访问。

6、哪些运算符是不允许重载的?

答:1、.(成员访问运算符)2、.*(成员指针访问运算符)3、::(域运算符)4、sizeof(长度运算符)5、?:(条件运算符)

7、为什么算术运算符“+”“-”“*”“/”应该重载为友元函数?

答:重载为成员函数不能满足使用要求,重载为普通函数又不能访问类的私有成员,所以需要将运算符重载为友元。

Guess you like

Origin blog.csdn.net/qq_59819866/article/details/131437954