BJFUOJ-C++程序设计-实验4-运算符重载

完整题目见BJFUOJ-C++程序设计-实验4-运算符重载-CSDN博客

A Singer类

答案:

#include<iostream>

using namespace std;

class Singer{    
private:
    string name;
    char sex;
    int age;
    double score;
public:
    string getName();   
    friend istream & operator>>(istream & in,Singer & s);
    friend ostream & operator<<(ostream & out,Singer & s);
    friend bool operator>(Singer & s1,Singer & s2);
    friend bool operator==(Singer & s1,Singer & s2);
};

string Singer::getName()
{
    return this->name;
}

istream & operator>>(istream & in,Singer & s)
{
    in>>s.name>>s.sex>>s.age>>s.score;
    return in;
}

ostream & operator<<(ostream & out,Singer & s)
{
    out<<s.name<<" "<<s.sex<<" "<<s.age<<" "<<s.score;
    return out;
}

bool operator>(Singer & s1,Singer & s2)
{
    if(s1.score>s2.score)
        return true;
    else
        return false;
}

bool operator==(Singer & s1,Singer & s2)
{
    if(s1.score==s2.score)
        return true;
    else
        return false;
}


int main()
{
    Singer s1,s2;
    cin>>s1>>s2;
    cout<<s1<<"\n"<<s2<<endl;

    if(s1>s2)
        cout<<s1.getName()<<"'s score is higher than "<<s2.getName()<<"'s.\n";
    else if(s1==s2)
        cout<<s1.getName()<<"'s score is equal to "<<s2.getName()<<"'s.\n";
    else
        cout<<s1.getName()<<"'s score is lower than "<<s2.getName()<<"'s.\n";

    return 0;
}

重要知识点:

简单运算符重载。

B Sales_data类

答案:

#include<iostream>

using namespace std;

class Sales_data {

//依次输入书号、销量和收入
    friend istream & operator>>(istream&, Sales_data &);
//依次输出书号、销量、收入和均价
    friend ostream & operator<<(ostream &, const Sales_data &);
    friend bool operator==(const Sales_data &, const Sales_data &);
    friend bool operator!=(const Sales_data &, const Sales_data &);
// for "+", assume that both objects refer to the same book
    friend Sales_data operator+(const Sales_data &, const Sales_data &);

public:
    Sales_data(): units_sold(0), revenue(0.0) {}
    Sales_data(const string & s, unsigned n, double r): bookNo(s), units_sold(n), revenue(r) {}
    string get_bookNo() const;
    // for "+=", assume that both objects refer to the same book
    Sales_data & operator+=(const Sales_data &);

private:
    double avg_price() const;  //均价,等于收入除以销量
    string bookNo;        //书号
    unsigned units_sold; //销量
    double revenue;      //收入
};

double Sales_data::avg_price() const
{
    return revenue/units_sold;
}

istream & operator>>(istream& is,Sales_data & s)
{
    is>>s.bookNo>>s.units_sold>>s.revenue;  

    return is;
} 
ostream & operator<<(ostream & os, const Sales_data & s)
{
    os<<s.bookNo<<" "<<s.units_sold<<" "<<s.revenue<<" "<<s.avg_price();
    return os;
}

bool operator==(const Sales_data & s1, const Sales_data & s2)
{
    if(s1.bookNo==s2.bookNo)
        return 1;
    else
        return 0;
}

bool operator!=(const Sales_data &s1, const Sales_data &s2)
{
    if(s1.bookNo==s2.bookNo)
        return 0;
    else
        return 1;
}

Sales_data operator+(const Sales_data &s1, const Sales_data &s2)
{
    Sales_data ts;
    ts.bookNo=s1.bookNo;
    ts.units_sold=s1.units_sold+s2.units_sold;
    ts.revenue=s1.revenue+s2.revenue;
    return ts;
}

string Sales_data::get_bookNo() const
{
    return this->bookNo;
}

Sales_data & Sales_data::operator+=(const Sales_data & s)
{
    this->revenue+=s.revenue;
    this->units_sold+=s.units_sold;
    return *this;
}

int main(){
    Sales_data item1,item2;

    while(cin>>item1>>item2){
        cout<<item1<<"\n"<<item2<<"\n";
        if(item1==item2)
            cout<<item1.get_bookNo()<<" equals "<<item2.get_bookNo()<<"\n";
        if(item1!=item2)
            cout<<item1.get_bookNo()<<" doesn't equal "<<item2.get_bookNo()<<"\n";
        cout<<(item1+item2)<<"\n";
        item1 += item2;
        cout<<item1<<"\n";
    }

    return 0;
}

重要知识点:

麻烦一点的简单运算符重载。

C Complex类

答案:

#include<iostream>
using namespace std;

class Complex
{
private:
    double x;
    double y;

public:
    Complex(double x = 0.0, double y = 0.0);
    Complex & operator+=(const Complex &);
    Complex & operator-=(const Complex &);
    Complex & operator*=(const Complex &);
    Complex & operator/=(const Complex &);

    friend Complex operator+(const Complex &, const Complex &);
    friend Complex operator-(const Complex &, const Complex &);
    friend Complex operator*(const Complex &, const Complex &);
    friend Complex operator/(const Complex &, const Complex &);
    friend bool operator==(const Complex &, const Complex &);
    friend bool operator!=(const Complex &, const Complex &);
    friend ostream & operator<<(ostream &, const Complex &);
    friend istream & operator>>(istream &, Complex &);
};

Complex::Complex(double x, double y)
{
    this->x=x;
    this->y=y;
}

Complex & Complex::operator+=(const Complex & c)
{
    this->x+=c.x;
    this->y+=c.y;
    return *this;
}

Complex & Complex::operator-=(const Complex & c)
{
    this->x-=c.x;
    this->y-=c.y;
    return *this;
}

//需要将临时变量保存原始数值,然后再进行计算操作
Complex & Complex::operator*=(const Complex & c)
{
    double tx=x;
    double ty=y;
    x=tx*c.x-ty*c.y;
    y=tx*c.y+ty*c.x;
    return *this;
}

Complex & Complex::operator/=(const Complex & c)
{
    double tx=x;
    double ty=y;
    this->x=(tx*c.x+ty*c.y)/(c.x*c.x+c.y*c.y);
    this->y=(ty*c.x-tx*c.y)/(c.x*c.x+c.y*c.y);
    return *this;
}

Complex operator+(const Complex &c1, const Complex &c2)
{
    Complex tc;
    tc.x=c1.x+c2.x;
    tc.y=c1.y+c2.y;
    return tc;
}

Complex operator-(const Complex &c1, const Complex &c2)
{
    Complex tc;
    tc.x=c1.x-c2.x;
    tc.y=c1.y-c2.y;
    return tc;
}

Complex operator*(const Complex &c1, const Complex &c2)
{
    Complex tc;
    tc.x=c1.x*c2.x-c1.y*c2.y;
    tc.y=c1.x*c2.y+c1.y*c2.x;
    return tc;
}

Complex operator/(const Complex &c1, const Complex &c2)
{
    Complex tc; 
    tc.x=(c1.x*c2.x+c1.y*c2.y)/(c2.x*c2.x+c2.y*c2.y);
    tc.y=(c1.y*c2.x-c1.x*c2.y)/(c2.x*c2.x+c2.y*c2.y);
    return tc;
}

bool operator==(const Complex &c1, const Complex &c2)
{
    if(c1.x==c2.x)
        return 1;
    else
        return 0; 
}

bool operator!=(const Complex &c1, const Complex &c2)
{
    if(c1.x==c2.x)
        return 0;
    else
        return 1;   
}

ostream & operator<<(ostream &os, const Complex &c)
{
    os<<c.x<<" + "<<c.y<<"i";
    return os;
}

istream & operator>>(istream &is, Complex &c)
{
    is>>c.x>>c.y;
    return is;
}

int main()
{
Complex c1, c2;

    cin >> c1 >> c2;
    cout << "c1 = " << c1 << "\n" << "c2 = " << c2 << endl;
    cout << "c1+c2 = " << c1 + c2 << endl;
    cout << "c1-c2 = " << c1 - c2 << endl;
    cout << "c1*c2 = " << c1 * c2 << endl;
    cout << "c1/c2 = " << c1 / c2 << endl;
    cout << (c1 += c2) << endl;
    cout << (c1 -= c2) << endl;
    cout << (c1 *= c2) << endl;
    cout << (c1 /= c2) << endl;
    cout << (c1 == c2) << " " << (c1 != c2) << endl;

    return 0;
}

重要知识点:

很经典全面的运算符重载实例,注意一下实现乘除法时需要将临时变量保存原始数值,然后再进行计算操作。

D String类 (重点学习)

描述:

实现以下String类:

class String
{
private:
char * s;
public:
String();
String(const char *);
String(const String &);
~String();
String & operator=(const char *);
String & operator=(const String &);
String operator+(const char *);
String operator+(const String &);
String & operator+=(const char *);
String & operator+=(const String &);
friend istream & operator>>(istream &, String &);
friend ostream & operator<<(ostream &, const String &);
friend bool operator==(const String &, const char *);
friend bool operator==(const String &, const String &);
friend bool operator!=(const String &, const char *);
friend bool operator!=(const String &, const String &);
};

使用以下main函数进行测试:

int main()
{
String s;
s += “hello”;
cout<> s3;
cout << s3 << endl;
String s4(“String4”), s5(s4);
cout << (s5 == s4) << endl;
cout << (s5 != s4) << endl;
String s6(“End of “), s7(“my string.”);
s6 += s7;
cout << s6 << endl;
return 0;
}

输入:

s3的值

输出:

见示例与主函数

输入样例:

   String3

输出样例:

hello
String1
copy of String1
String3
1
0
End of my string.

答案:

#include<iostream>
#include<cstring>
using namespace std;

class String
{
private:
    char* s;

public:
    String();
    String(const char*);
    String(const String&);
    ~String();

    String& operator=(const char*);
    String& operator=(const String&);
    String operator+(const char*);
    String operator+(const String&);
    String& operator+=(const char*);
    String& operator+=(const String&);

    friend istream& operator>>(istream&, String&);
    friend ostream& operator<<(ostream&, const String&);
    friend bool operator==(const String&, const char*);
    friend bool operator==(const String&, const String&);
    friend bool operator!=(const String&, const char*);
    friend bool operator!=(const String&, const String&);
};

String::String()
{
    s = new char[1];
    s[0]='\0';
    //s=NULL;
}

String::String(const char* tc)
{
    s = new char[strlen(tc) + 1];
    strcpy(s, tc);
}

String::String(const String& ts)
{
    s = new char[strlen(ts.s) + 1];
    strcpy(s, ts.s);
}

String::~String()
{
    delete[] s;
}

String& String::operator=(const char* tc)
{
    s = new char[strlen(tc) + 1];
    strcpy(s, tc);
    return *this;
}

String& String::operator=(const String& ts)
{
    s = new char[strlen(ts.s) + 1];
    strcpy(s, ts.s);
    return *this;
}

String String::operator+(const char* tc)
{
    String news;
    news.s = new char[strlen(s) + strlen(tc) + 1];
    strcpy(news.s, s);
    strcat(news.s, tc);
    return news;
}

String String::operator+(const String& ts)
{
    String news;
    news.s = new char[strlen(s) + strlen(ts.s) + 1];
    strcpy(news.s, s);
    strcat(news.s, ts.s);
    return news;
}

String& String::operator+=(const char* tc)
{
    char* news = new char[strlen(s) + strlen(tc) + 1];
    strcpy(news, s);
    strcat(news, tc);
    delete[] s;
    s = news;
    return *this;
}

String& String::operator+=(const String& ts)
{
    char* news = new char[strlen(s) + strlen(ts.s) + 1];
    strcpy(news, s);
    strcat(news, ts.s);
    delete[] s;
    s = news;
    return *this;
}

istream& operator>>(istream& is, String& ts)
{

    char temp[100];
    is >> temp;
    delete[] ts.s;
    ts.s = new char[strlen(temp) + 1];
    strcpy(ts.s, temp);
    return is;
}

ostream& operator<<(ostream& os, const String& ts)
{
    os << ts.s;
    return os;
}

bool operator==(const String& ts, const char* tc)
{
    return (strcmp(ts.s, tc) == 0);
}

bool operator==(const String& ts1, const String& ts2)
{
    return (strcmp(ts1.s, ts2.s) == 0);
}
bool operator!=(const String& ts, const char* tc)
{
    return !(strcmp(ts.s, tc) == 0);
}

bool operator!=(const String& ts1, const String& ts2)
{
    return !(strcmp(ts1.s, ts2.s) == 0);
}


int main()
{
    String s;
    s += "hello";
    cout << s << endl;
    String s1("String1");
    String s2("copy of ");
    s2 += "String1";
    cout << s1 << "\n" << s2 << endl;
    String s3;
    cin >> s3;
    cout << s3 << endl;
    String s4("String4"), s5(s4);
    cout << (s5 == s4) << endl;
    cout << (s5 != s4) << endl;
    String s6("End of "), s7("my string.");
    s6 += s7;
    cout << s6 << endl;

    return 0;
}

重要知识点:

1.首先注意到成员是个字符指针,要想到new与delete、浅拷贝与深拷贝相关知识。
2.无参构造函数:

String::String()
{
    s = new char[1];
    s[0]='\0';
    //s=NULL;
}
要为类的成员变量s动态分配内存来存储字符串。由于字符串是以\0结尾的字符数组,
所以需要为s分配一个长度为1的字符数组,并将数组的第一个元素设为字符’\0’,以表示空字符串的结束。
这样可以确保s成员变量始终以空字符串结尾,从而正确表示一个空的String对象。

而s=NULL不行:因为String类表示的是一个字符串对象,
如果将s赋值为NULL,那么s将指向空地址,而不是一个空字符串。这样会导致后续对s操作时出现错误。

3.两个拷贝构造函数:

String::String(const char* tc)
{
    s = new char[strlen(tc) + 1];
    strcpy(s, tc);
}

String::String(const String& ts)
{
    s = new char[strlen(ts.s) + 1];
    strcpy(s, ts.s);
}

首先为s申请足够的空间,再通过strcpy()实现字符串的深拷贝。

4.注意析构函数中使用delete。
5.对=重载时要删除原来的值;
6.对+重载时逻辑为创造一个新对象,strcpy前一个字符串,再strcat加上后一个字符串。最后返回这个新对象。
7.+=与+区别:
创建的是char* 而非string类对象(最后直接赋予String.s);
s = news;前delete原先对象。
最后返回的是自己。
8.>>的重载:
直接is>>ts.s也能通过但并不符合常理,应该按上文写法;
9.strcmp的返回值;(为0为相等)

E CheckedPtr

答案:

#include<iostream>
using namespace std;

class CheckedPtr
{
public:
    CheckedPtr(int * b, int * e) : beg(b), end(e), curr(b) {  }
    CheckedPtr & operator ++(); // prefix ++
    CheckedPtr & operator --(); // prefix --
    CheckedPtr   operator ++(int); // postfix ++
    CheckedPtr   operator --(int); // postfix --
    int * GetBeg();
    int * GetEnd();
    int * GetCurr();

private:
    int * beg;  // pointer to beginning of the array
    int * end;  // one past the end of the array
    int * curr; // current position within the array
};

CheckedPtr & CheckedPtr::operator ++()
{
    ++curr;
    return *this;
}

CheckedPtr & CheckedPtr::operator --()
{
    --curr;
    return *this;
}

CheckedPtr   CheckedPtr::operator ++(int)
{
    CheckedPtr temp = *this;
    ++curr;
    return temp;
}

CheckedPtr   CheckedPtr::operator --(int)
{
    CheckedPtr temp = *this;
    --curr;
    return temp;
}

int * CheckedPtr::GetBeg()
{
    return beg;
}

int * CheckedPtr::GetEnd()
{
    return end;
}

int * CheckedPtr::GetCurr()
{
    return curr;
}

int main(){
    int n;
    cin>>n;
    int * array = new int[n];

    for(int i=0;i<n;i++)
        cin>>array[i];
    CheckedPtr cp(array, array+n);
    for(;cp.GetCurr()<cp.GetEnd();cp++)
        cout<<*cp.GetCurr()<<" ";
    cout<<endl;
    for(--cp;cp.GetCurr()>cp.GetBeg();cp--)
        cout<<*cp.GetCurr()<<" ";
    cout<<*cp.GetCurr()<<endl;
    delete [] array;

return 0;

}

重要知识点:

这里主要关注前缀++/–与后缀++/–的写法及其区别。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇