《C++程序设计》实验报告(三)之 类的基本操作和运算符重载的设计与实现

一、实验目的:

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";

}

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

实现方法:

(1)类Person有姓名、职务和指向领导的指针等私有数据,以及两个构造函数和以下成员函数:setleader()(设置当前职工的领导);getname()(获得职工成员);getleader()(获取领导者对象指针);disp()(输出姓名和职务)。

(2)定义如下样式的主函数。

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]);

cout<<"  姓名   职务    领导姓名\n";

cout<<"-------------------------\n";

for(int i=0;i<6;i++)

{  p[i].disp();

   printf("%10s\n",(p[i].getleader())->getname());

}

} 

程序:

#include<iostream>

#include<stdio.h>

#include<string.h>

using namespace std;

class Person

{

    char name[10];

    char prof[10];

    Person* leader;

public:

    Person() { strcpy_s(name, "\0"); }

    Person(const char n[], const char p[])

    {

        strcpy_s(name, n);

        strcpy_s(prof, p);

        leader = new Person;

    }

    void setleader(Person& p) { leader = &p; } // 对象引用作为参数

    char* getname() { return name; }

    Person* getleader()

    {

        return leader;

    }

    void disp()

    {

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

    }

};

int 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]);

    cout << "╔════════════════════════════════╗" << endl;

    cout << "║    姓名   ║   职务   ║ 领导姓名║" << endl;

    cout << "╚════════════════════════════════╝" << endl;

    for (int i = 0; i < 6; i++)

    {

        p[i].disp();

        printf("%10s\n", (p[i].getleader())->getname());

    }

}

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

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();            //求三个数据成员中的最大者

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

void print();       //屏幕显示数据成员

};

编写主函数,对所定义的类模板实例化而后进行应用,验证其正确性。

实现方法:

(1)编写类模板myTmplt中各成员函数的实现代码,完成对它们的具体定义。

(2)可编写类似于如下样式的主函数,对所定义的类模板进行使用。

void 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’);

……

    }

程序:

#include <iostream>

using namespace std;

#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() {

        if (x > y) {

            if (x > z) {

                return x;

            }

            else {

                return z;

            }

        }

        else {

            if (y > z) {

                return y;

            }

            else {

                return z;

            }

        }

    }            //求三个数据成员中的最大者

    bool order() {

        if (x <= y && y <= z) {

            return 1;

        }

        else {

            return 0;

        }

    }       //三个数据成员从小到大是否有序

    void print() {

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

    }       //屏幕显示数据成员

};

void 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;

    else

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

    system("pause");

}

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

实现方法:

(1)将学生类student的trans()函数设计成友元函数。

(2)可在学生类student中定义私有数据name、deg、level,定义带参构造函数、成员函数getname()、disp(),定义友元函数trans()(student &s)。

(3)编写主函数,实现本题功能,函数原型样式可按如下定义。

void 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();

}

}                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 

程序:

#include<iostream>

using namespace std;

#include<string>

class student

{

 friend void trans(student& s);

private:

 string name;

 int deg;

public:

 student() {}

 student(string name, int deg)

 {

  this->name = name;

  this->deg = deg;

 }

 string level;

 void disp()//≥90,优;80~89,中;70~79,中;60~69,及格;<60,不及格。

 {

  if (deg < 60) { this->level = "不及格"; }

  if (60 <= deg <= 69) { this->level = "及格"; }

  if (70 <= deg <= 89) { this->level = "中"; }

  if (deg >= 90) { this->level = "优秀"; }

  cout << level << endl;

 }

};

void trans(student& s)

{

 cout << "          " << s.name << "      " << s.deg << "        ";

}

string setw(int n)

{

 string w;

 for (int i = 0; i < n; i++)

 {

  w += " ";

 }

 return w;

}

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();

 }

}

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

实现方法:

(1)要求重载运算符“+”、“-”的函数为成员函数,重载运算符“*”、“/”的函数为友元函数。

(2)方法如第1题的(1)—(5)。

程序:

程序:

#include <iostream>

using namespace std;

class Complex

{

public:

    friend Complex operator+(Complex c1, Complex c2);

    friend Complex operator-(Complex c1, Complex c2);

    friend Complex operator*(Complex c1, Complex c2);

    friend Complex operator/(Complex c1, Complex c2);

    Complex(float r, float i)

    {

        imag = i; real = r;

    }

    void disp()

    {

        cout << real;

        if (imag > 0)

        {

            cout << "+";

        }

        if (imag != 0)

        {

            cout << imag << "i";

        }

        cout << endl;

    }

private:

    float real, imag;

};

Complex operator+(Complex c1, Complex c2)

{

    Complex temp(0, 0);

    temp.real = c1.real + c2.real;

    temp.imag = c1.imag + c2.imag;

    return temp;

}

Complex operator-(Complex c1, Complex c2)

{

    Complex temp(0, 0);

    temp.real = c1.real - c2.real;

    temp.imag = c1.imag - c2.imag;

    return temp;

}

Complex operator*(Complex c1, Complex c2)

{

    Complex temp(0, 0);

    temp.real = c1.real * c2.real - c1.imag * c2.imag;

    temp.imag = c1.real * c2.imag + c1.imag * c2.real;

    return temp;

}

Complex operator/(Complex c1, Complex c2)

{

    Complex temp(0, 0);

    temp.real = (c1.real * c2.real + c1.imag * c2.imag) / (c2.imag * c2.imag + c2.real * c2.real);

    temp.imag = (c1.imag * c2.real - c1.real * c2.imag) / (c2.imag * c2.imag + c2.real * c2.real);

    return temp;

}

int main()

{

    float a, b, c, d;

    cout << "输入两个数字的实部和虚部" << endl;

    cin >> a >> b >> c >> d;

    Complex c1(a, b), c2(c, d), c3(0, 0);

    cout << "这两个数字分别是" << endl;

    c1.disp(); c2.disp();

    cout << "他们的和是:";

    (c1 + c2).disp();

    cout << "他们的差是:";

    c3 = c1 - c2;

    c3.disp();

    cout << "他们的乘积是:";

    (c1 * c2).disp();

    cout << "他们相除是:";

    (c1 / c2).disp();

    system("pause");

    return 0;

}

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

实现方法:

(1)首先假定矩阵行、列数r和c为固定常数,且被处理的矩阵数据存放于matrix类的私有数据成员mem数组之中,并以类成员方式重载各运算符。可按照如下样式自定义该matrix类。

const int r=3;

const int c=3;

class matrix

{   int mem[r][c];            //矩阵r行c列的数据存放于mem数组中

 public:

};

(2)编写类似于如下形式的主函数,对matrix类对象及各种重载运算符进行使用,以验证它们的正确性。

void main()

{  int a[3][3]={}1,2,3,4,5,6,7,8,9};

   int b[3][3]={}1,2,3,0,1,2,-1,0,1};

   matrix x(a),y(b);

cout<<“----------x=-------------”<<endl;

x.display();

cout<<“----------y=-------------”<<endl;

y.display();

cout<<“----------x+y=-------------”<<endl;

(x+y).display();

cout<<“----------x-y=-------------”<<endl;

(x-y).display();

cout<<“----------x*y=-------------”<<endl;

(x*y).display();

cout<<“----------~x=-------------”<<endl;

(~x).display();

}

程序:

#include <iostream>

using namespace std;

const int r = 3;

const int c = 3;

const int k = 3;

class matrix

{

    int a[r][c];

public:

    matrix() {}

    matrix(int t[r][c])

    {

        for (int i = 0; i < r; i++)

            for (int j = 0; j < c; j++)

                a[i][j] = t[i][j];

    }

    friend matrix operator+ (matrix& a, matrix& b);  //矩阵加

    friend matrix operator- (matrix& a, matrix& b);  //矩阵减

    friend matrix operator* (matrix& a, matrix& b);  //矩阵乘  

    friend matrix operator~ (matrix& a); //矩阵转置

    void display();

};  //注意分号

matrix operator +(matrix& a, matrix& b)   //分号去掉

{

    matrix ret;

    for (int i = 0; i < r; i++)

        for (int j = 0; j < c; j++)

            ret.a[i][j] = a.a[i][j] + b.a[i][j];

    return ret;

}

matrix operator -(matrix& a, matrix& b)

{

    matrix ret;

    for (int i = 0; i < r; i++)

        for (int j = 0; j < c; j++)

            ret.a[i][j] = a.a[i][j] - b.a[i][j];

    return ret;

}

matrix operator* (matrix& a, matrix& b)

{

    matrix ret;

    for (int i = 0; i < r; i++)

        for (int j = 0; j < c; j++)

        {

            ret.a[i][j] = 0;

            for (int l = 0; l < k; l++)

                ret.a[i][j] = a.a[i][j] + b.a[i][j];

        }

    return ret;

}

matrix operator~ (matrix& a)

{

    matrix ret;

    for (int i = 0; i < r; i++)

        for (int j = 0; j < c; j++)

            ret.a[j][i] = ~a.a[i][j];

    return ret;

}

void matrix::display()

{

    for (int i = 0; i < r; i++)

    {

        for (int j = 0; j < c; j++)

            cout << this->a[i][j] << " ";

        cout << endl;

    }

}

int main()

{

    int a[3][3] = { 1,2,3,4,5,6,7,8,9 };

    int b[3][3] = { 1,2,3, 0,1,2, -1,0,1 };

    matrix x(a);

    matrix y(b);

    cout << "-------- x= ------------" << endl;

    x.display(); //按设定格式显示出第一个矩阵

    cout << "-------- y= ------------" << endl;

    y.display(); //按设定格式显示出第二个矩阵  

    cout << "-------- x+y= ------------" << endl;

    (x + y).display(); //输出结果矩阵 x+y  

    cout << "--------- x-y= ---------" << endl;

    (x - y).display(); //输出结果矩阵x-y  

    cout << "--------- x*y= ---------" << endl;

    (x * y).display(); //输出结果矩阵x*y  

    cout << "--------- ~x= ---------" << endl;

    (~x).display(); //输出结果矩阵~x

    system("PAUSE");

}

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

实现方法:

(1)可定义如下样式的类String。

class String

{ public:

    String( ){ p=NULL; }         //默认构造函数

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

   void display( );

  private:

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

};

  1. 重载运算符函数为友元函数。

程序:

#include<iostream>

#include<cstring>

using namespace std;

class String

{

public:

String()//默认构造函数

{

p = NULL;

}

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

void display();

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;}

void String::display()

{

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("discourage"), string2("analyse"), string3("numerous"), string4("discourage");//定义对象

compare(string1, string2);

compare(string2, string3);

compare(string1, string4);

return 0;

}

分析与讨论:

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

答:对象的赋值是对一个已经存在的对象赋值,因此必须先定义被赋值的对象,才能进行对象的赋值。而对象的复制则是从无到有地建立一个新对象,并使它与一个已有的对象的完全相同 (包括对象的结构和成员的值)。

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

答:使用一个已经存在的对象(此对象由复制构造函数的参数决定),去初始化同类的一个新对象。

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

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

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

答:

特点:不管这个类创建多少个对象,其静态成员在内存中只保留一份副本,这个副本为该类的所有对象所共享。面对对象方法中还有类属性的概念,类属性是描述类的所有对象的共同特征的一个数据项,对于任何对象实例,它的属性值是相同的,C++通过静态数据成员来实现类属性。

优势:静态数据成员没有进入程序的全局名字空间,因此不存在与程序中其它全局名字冲突的可能性;可以实现信息隐藏。

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

答:运算对象的个数是2的运算符称为双目运算符

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

(1).(成员访问运算符)

(2)*(成员指针访问运算符)

(3)::(域运算符)

(4)sizeof(长度运算符)

(5)?:(条件运算符)

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

答:多元运算符重载为成员函数的时候,是调用的第一个运算数的成员函数

  • 23
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
为了方便,把代码放在Word里面了,每次上机实验的题目代码都在。 第一次: 对如下多项式编写定义: + + +…+ 其中,n为多项式的次数。完成如下功能: (1) 可存储任意大的多项式(提示:可用动态数组实现)。 (2) 定义构造函数、析构函数、拷贝构造函数。 (3) 包含一个static成员存储定义的多项式的数量。 (4) 定义一个成员函数输出多项式。(可参照-x^4-6x^3+5格式输出) (5) 定义一个成员函数计算多项式的值。 (6) 写main函数测试的功能。 (7) 采用多文件实现。 考虑:哪些成员函数可以声明为const. 第二次: (8) 重载“+”运算符,实现两个多项式相加。 (9) 重载“-”运算符,实现两个多项式相减。 (10) 重载“*”运算符,实现两个多项式相乘。 (11) 重载“=”运算符,实现两个多项式的赋值运算。 考虑:把其中某个运算符重载为友元函数。 第次: C++的一般编译器都定义和封装了字符串功能,请模仿定义string实现,可以实现并支持如下功能: (1)string s = “吉林大学”; (2)string t = s; (3)string m; m = t; (4)m.legnth() 函数测量字符串的长度 (5)m.cat(string const &)连接字符串 第四次: 我公司为仪器生产企业,目前生产摄像机和行车记录仪两种产品,分别销售给用户。 摄像机包含摄像、图像质量设定、编码算法等属性。 将摄像机增加相应芯片(具有操作菜单、自动拍摄、车速传感器、源代码等功能)后,形成一个行车记录仪。 要求: 设计摄像机,并请根据下列不同的功能要求,采用不同的继承方式,设计行车记录仪,并添加测试代码,体验不同继承方式下的成员访问属性。(设计时可根据需要自行添加数据成员和其他成员函数。) (1) 行车记录仪的芯片可以使用摄像机的摄像、图像质量设定功能。 行车记录仪用户可以操作行车记录仪的操作菜单和摄像机的摄像功能。 (2)行车记录仪的芯片可以使用摄像机的拍摄、图像质量设定功能。 行车记录仪用户仅仅可以操作行车记录仪的操作菜单。 (3) 行车记录仪的芯片可以使用摄像机的拍摄、图像质量设定功能。 行车记录仪用户仅仅可以操作行车记录仪的操作菜单 同时其他公司购买行车记录仪,因该公司也用于销售,不得泄露其全部内容 课后: (1)采用组合方式设计行车记录仪,增加相应测试代码,体验继承和组合的关系。 (2)分别为继承和组合方式下为各添加构造函数、析构函数,增加相应测试代码,体验对象的初始化和构造顺序。 (3)将摄像机和行车记录仪功能相近的函数(如拍摄、编码等功能函数)设为同名函数,增加相应测试代码,体验同名函数覆盖。 (4)为我公司建立一个多态的产品层次结构,使用抽象,测试时,创建一个基指针的容器,通过基指针调用虚函数,体验多态。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

了一li

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值