头歌平台:程序设计二(面向对象)_实训7_赋值运算符重载

第1关:拷贝赋值运算符重载

任务描述

首先,赋值运算符重载必须使用成员函数形式。其次,拷贝赋值运算符是指形参为本类型的常引用的赋值运算符。也有直接以本类型为参数的拷贝赋值,但是不常见。通常拷贝赋值运算符重载的参数与拷贝构造函数保持一致。

相关知识

运算符重载,相当于一个固定了函数名的函数。以重载加号运算符为例,其函数名就是

 
  1. operator +

运算符重载不能改变运算符的优先级与结合性,本质上也不能改变参数的数量(即双目运算符重载,必须拥有 2 个形参)。但是,如果以成员函数进行重载,则参数数量需要减一。减掉的那个参数,实际上就是调用该运算符时的类对象。

运算符重载的使用有 2 种形式,运算符形式和函数形式。以加号运算符为例,如果是成员函数形式重载,则:

 
  1. Int a,b,c;
  2. c = a + b;//运算符形式调用
  3. c = a.operator + (b);//成员函数形式调用

如果是以普通函数形式重载,则:

 
  1. Int a,b,c;
  2. c = a + b;
  3. c = operator + (a,b);

出于某种“对称性”的考虑,一般习惯使用普通函数来重载算术运算符。 事实上,如果你不进行拷贝赋值运算符重载,系统会主动为你添加一个拷贝赋值运算符重载,就如同拷贝构造函数、析构函数那样。

对这里的 Int 类而言,其实写不写拷贝赋值,都不影响程序的运行。不过还是要求按拷贝赋值运算符重载的标准范式进行书写。

编程要求

根据提示,在右侧编辑器的Begin-End区域内补充代码。

测试说明

本关有 2 个文件,main.cpp 和 Int.h,用户需要补齐 Int.h 内的相应内容。

main.cpp 的内容如下:

  1. #include <iostream>
  2. #include "Int.h"
  3. using namespace std;
  4. int main(){
  5. Int a,b;
  6. int x;
  7. cin>>x;
  8. a.setValue(x);
  9. b = a;
  10. cout<<b.getValue()<<endl;
  11. return 0
  1. /**
     * ?aê?ò???°ü×°àà(wrapper class)£?°ü×°àà?úC++?DóDμ?D?D?μ?ó?′|(?ù±?é???ó?)£??úJava?Dμ?ó?′|?ü′óò?D?£
     */
    #ifndef _INT_H_  //?aê?define guard 
    #define _INT_H_  //?úCoíC++?D£?í·???t??ó|??óD?aí?òa 
    
    class Int{
    private://?aê?·??ê?????a?a??óDμ? 
        int value; //?aê?êy?Y3é?±£??ò??3?Intê??ù±?ààDíintμ?°ü×°àà£??íê?òò?aIntà?????óDò???intààDíμ?êy?Y3é?± 
        
    public:    //?aê?1?óDμ? 
        Int():value(0){}
        Int(Int const&rhs):value(rhs.value){}
        Int(int v):value(v){}
        
        int getValue()const{return value;}
        void setValue(int v){value=v;}
    
        //??±′?3?μ????·?????
        Int& operator = (const Int&rhs){
            //?ú?aà?D′??ì?êμ??£?×¢òa×?×??ò?3?μμ??ì2a
            value=rhs.value;
    
        }
    
    };//??×??aà?óDò???·?o? 
    
    #endif
    

任务描述

赋值运算符重载只能拥有一个形参。但是只要形参的类型不同,就能进行多个赋值运算符重载。这里重载一个以基本类型 int 为形参的赋值运算符。

相关知识

实际上,即使不重载这个运算符,相应的赋值操作也能进行。这是因为C++系统会尝试调用构造函数。

也就是说,如下代码

Int a; a = 3;

如果你重载了以int为形参的赋值运算符,就相当于:

如果你没有重载该赋值运算符,则相当于:

编程要求

根据提示,在右侧编辑器的Begin-End区域内补充代码。

测试说明

如果你既没有重载该赋值运算符,也没有提供该构造函数,则上述程序是不能通过编译的。

本关有 2 个文件,main.cpp 和 Int.h,用户需要补齐 Int.h 内的相应内容。

main.cpp 的内容如下:

  1. a.operator = (3);//3是一个int
  2. a = Int(3);
  3. #include <iostream>
  4. #include "Int.h"
  5. using namespace std;
  6. int main(){
  7. Int a;
  8. int x;
  9. cin>>x;
  10. a = x;
  11. cout<<a.getValue()<<endl;
  12. return 0;
  13. }
  14. #include <iostream>
  15. #include "Int.h"
  16. using namespace std;
  17. int main(){
  18. Int a;
  19. int x;
  20. cin>>x;
  21. a = x;
  22. cout<<a.getValue()<<endl;
  23. return 0;
  24. }

 

/**
 * ?aê?ò???°ü×°àà(wrapper class)£?°ü×°àà?úC++?DóDμ?D?D?μ?ó?′|(?ù±?é???ó?)£??úJava?Dμ?ó?′|?ü′óò?D?£
 */
#ifndef _INT_H_  //?aê?define guard 
#define _INT_H_  //?úCoíC++?D£?í·???t??ó|??óD?aí?òa 

class Int{
private://?aê?·??ê?????a?a??óDμ? 
    int value; //?aê?êy?Y3é?±£??ò??3?Intê??ù±?ààDíintμ?°ü×°àà£??íê?òò?aIntà?????óDò???intààDíμ?êy?Y3é?± 
    
public:    //?aê?1?óDμ? 
    Int():value(0){}
    Int(Int const&rhs):value(rhs.value){}
    
    int getValue()const{return value;}
    void setValue(int v){value=v;}

    //?????3?μ????·?????
    Int& operator = (int rhs){
        //?ú?aà?D′??ì?êμ??
       this->value=rhs; 
    }

};//??×??aà?óDò???·?o? 

#endif

第3关:算术复合赋值符运算符重载 

任务描述

一个令人惊讶的事实是复合赋值符运算符既能以成员函数进行重载,也能以普通函数进行重载。但是建议大家以成员函数的形式进行重载。

相关知识

这里,仅重载算术复合赋值运算符。另一个建议是,如果你重载了赋值运算符,又重载了算术运算符,你应该考虑重载算术复合赋值运算符。

编程要求

根据提示,在右侧编辑器的Begin-End区域内补充代码。

测试说明

本关有 2 个文件,main.cpp 和 Int.h,用户需要补齐 Int.h 内的相应内容。

main.cpp 的内容如下:

 
  1. #include <iostream>
  2. #include "Int.h"
  3. using namespace std;
  4. int main(){
  5. int x,y;
  6. cin>>x>>y;
  7. Int a(x),b(y);
  8. a += b;
  9. cout<<a.getValue()<<" "<<b.getValue()<<endl;
  10. return 0;
  11. }
    /**
     * ?aê?ò???°ü×°àà(wrapper class)£?°ü×°àà?úC++?DóDμ?D?D?μ?ó?′|(?ù±?é???ó?)£??úJava?Dμ?ó?′|?ü′óò?D??£
     */
    #ifndef _INT_H_  //?aê?define guard 
    #define _INT_H_  //?úCoíC++?D£?í·???t??ó|??óD?aí?òa 
    
    class Int{
    private://?aê?·??ê?????a?a??óDμ? 
        int value; //?aê?êy?Y3é?±£??ò??3?Intê??ù±?ààDíintμ?°ü×°àà£??íê?òò?aIntà?????óDò???intààDíμ?êy?Y3é?± 
        
    public:    //?aê?1?óDμ? 
        Int():value(0){}
        Int(Int const&rhs):value(rhs.value){}
        Int(int v):value(v){}
        
        int getValue()const{return value;}
        void setValue(int v){value=v;}
    
        //??ê??′o??3?μ????·?????·?????
        Int& operator += (const Int&rhs){
            //?ú?aà?êμ????ê??′o??3?μ????·?
             value=value+rhs.value;
        }
    
    };//??×??aà?óDò???·?o? 
    
    #endif
    
    

第4关:复用算术运算符重载复合赋值运算符 

任务描述

写一个完整的包含赋值运算符、算术运算符以及复合赋值运算符的重载代码。并且使用函数复用技术。

相关知识

按照学习的顺序,假定首先实现了赋值运算符以及算术运算符,现在要求利用前二者来实现复合赋值运算符。

此处插一句,这样写并不完美,真正好的做法是利用复合赋值运算符来实现算术运算符,就像下一关那样。原因是出于效率,大家可以自行对比本关与下一关可能的效率上的区别。

编程要求

根据提示,在右侧编辑器的Begin-End区域内补充代码。

测试说明

本关有 3 个文件,main.cpp 和 Int.h 以及 Int.cpp,用户需要书写 Int.cpp 内的相应内容。

main.cpp 的内容如下:

  1. #include <iostream>
  2. #include "Int.h"
  3. using namespace std;
  4. int main(){
  5. int x,y;
  6. cin>>x>>y;
  7. Int a(x),b(y);
  8. a += b;
  9. cout<<a.getValue()<<" "<<b.getValue()<<endl;
  10. return 0;
  11. }

Int.h 文件的内容如下

  1. /**
  2. * 这是一个包装类(wrapper class),包装类在C++中有点小小的用处(基本上没用),在Java中的用处更大一些。
  3. */
  4. #ifndef _INT_H_ //这是define guard
  5. #define _INT_H_ //在C和C++中,头文件都应该有这玩意
  6. class Int{
  7. private://这是访问控制——私有的
  8. int value; //这是数据成员,我们称Int是基本类型int的包装类,就是因为Int里面只有一个int类型的数据成员
  9. public: //这是公有的
  10. Int():value(0){}
  11. Int(Int const&rhs):value(rhs.value){}
  12. Int(int v):value(v){}
  13. int getValue()const{return value;}
  14. void setValue(int v){value=v;}
  15. //拷贝赋值运算符重载
  16. Int& operator = (const Int&rhs);
  17. //算术复合赋值运算符声明
  18. Int& operator += (const Int&rhs);
  19. };//记住这里有一个分号
  20. //算术运算符声明
  21. Int operator + (const Int&lhs,const Int&rhs);
  22. #endif
    /********** BEGIN **********/
    
    #include"Int.h"
    Int& Int::operator=(const Int&rhs)
    {
         this->setValue(rhs.getValue());
         return *this;
        
    }
    Int& Int::operator+=(const Int&rhs)
    {
         this->setValue(this->getValue()+rhs.getValue());
         return *this;
        
    }
    Int operator+(const Int&lhs,const Int&rhs)
    {
        Int m;
        m.setValue(lhs.getValue()+rhs.getValue());
        return m;
    
    }
    
    
    /********** END **********/

第5关:复用复合赋值运算符重载算术运算符 

任务描述

如果你不觉得啰嗦,或者你有程序员型强迫症的话,这里是一个完美的赋值运算符、算术运算符与复合赋值运算符的重载。

相关知识

首先重载赋值运算符与算术复合赋值运算符,然后利用前二者实现算术运算符重载。

编程要求

根据提示,在右侧编辑器的Begin-End区域内补充代码。

测试说明

本关有 3 个文件,main.cpp 和 Int.h 以及 Int.cpp,用户需要书写 Int.cpp 内的相应内容。

main.cpp 的内容如下:

 
  1. #include <iostream>
  2. #include "Int.h"
  3. using namespace std;
  4. int main(){
  5. int x,y;
  6. cin>>x>>y;
  7. Int a(x),b(y);
  8. a += b;
  9. cout<<a.getValue()<<" "<<b.getValue()<<endl;
  10. return 0;
  11. }

Int.h 文件的内容如下

 
  1. /**
  2. * 这是一个包装类(wrapper class),包装类在C++中有点小小的用处(基本上没用),在Java中的用处更大一些。
  3. */
  4. #ifndef _INT_H_ //这是define guard
  5. #define _INT_H_ //在C和C++中,头文件都应该有这玩意
  6. class Int{
  7. private://这是访问控制——私有的
  8. int value; //这是数据成员,我们称Int是基本类型int的包装类,就是因为Int里面只有一个int类型的数据成员
  9. public: //这是公有的
  10. Int():value(0){}
  11. Int(Int const&rhs):value(rhs.value){}
  12. Int(int v):value(v){}
  13. int getValue()const{return value;}
  14. void setValue(int v){value=v;}
  15. //拷贝赋值运算符重载
  16. Int& operator = (const Int&rhs);
  17. //算术复合赋值运算符声明
  18. Int& operator += (const Int&rhs);
  19. };//记住这里有一个分号
  20. //算术运算符声明
  21. Int operator + (const Int&lhs,const Int&rhs);
  22. #endif
    /********** BEGIN **********/
    
    
    #include"Int.h"
    Int& Int::operator=(const Int&rhs)
    {
         this->setValue(rhs.getValue());
         return *this;
        
    }
    Int& Int::operator+=(const Int&rhs)
    {
         this->setValue(this->getValue()+rhs.getValue());
         return *this;
        
    }
    Int operator+(const Int&lhs,const Int&rhs)
    {
        Int m;
        m+=lhs;
        m+=rhs;
        return m;
    }
    
    
    
    /********** END **********/
    
  • 7
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
赋值运算符重载为一个类定义一个赋值运算符,以实现在对象间赋值的操作。在 C++ 中,赋值运算符重载函数的函数名必须为 operator=,其格式如下: ``` class_name& operator=(const class_name& rhs){ //实现赋值操作 return *this; } ``` 其中,class_name 为类名,rhs 为右操作数,即赋值号右侧的值。重载赋值运算符函数必须返回一个向当前对象的引用,以支持链式赋值操作。 下面是一个实现自定义类的赋值运算符重载的例子: ```c++ #include <iostream> using namespace std; class MyString { public: MyString() : buffer(NULL), size(0) { } MyString(const char* input) { if (input != NULL) { size = strlen(input); buffer = new char[size + 1]; strcpy(buffer, input); } else { buffer = NULL; size = 0; } } MyString(const MyString& copySource) { if (copySource.buffer != NULL) { size = copySource.size; buffer = new char[size + 1]; strcpy(buffer, copySource.buffer); } else { buffer = NULL; size = 0; } } ~MyString() { if (buffer != NULL) { delete[] buffer; buffer = NULL; size = 0; } } MyString& operator=(const MyString& copySource) { if ((this != &copySource) && (copySource.buffer != NULL)) { if (buffer != NULL) { delete[] buffer; } size = copySource.size; buffer = new char[size + 1]; strcpy(buffer, copySource.buffer); } return *this; } int GetLength() const { return size; } const char* GetString() const { return buffer; } private: char* buffer; unsigned int size; }; int main() { MyString str1("Hello"); MyString str2("World"); str2 = str1; cout << str2.GetString() << endl; return 0; } ``` 在上面的例子中,MyString 类重载了赋值运算符=,实现了一个深拷贝的操作。当赋值号左右两侧的对象不相同时,才进行赋值操作。同时,在进行赋值操作前,会先释放已有的 buffer,再根据源字符串的长度重新分配内存。 运行结果为: ``` Hello ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值