C语言/C++ 之 类的基本操作和运算符的重载的设计与实验(3/5)

一、实验目的:

1.了解面向对象的程序设计的特点、思想,了解类的封装性和信息隐蔽。

2.掌握类和对象的定义和作用,熟练应用类和对象。

3.掌握类的成员函数的定义,熟练定义、应用类的成员函数。

4.掌握对象成员的引用,熟练应用对象成员的引用。

5.掌握构造函数、析构函数,要求熟练应用。

二、实验内容

  1. 读程序,分析它执行后的输出结果,并上机进行测试验证。

程序代码:

#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、为什么算术运算符“+”“-”“*”“/”应该重载为友元函数?

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

猜你喜欢

转载自blog.csdn.net/qq_59819866/article/details/131437954