武汉c培训
达内武汉中心

15271940953

热门课程

武汉C++培训:重载=(赋值运算符)

  • 时间:2016-05-12
  • 发布:武汉C++培训
  • 来源:c语言教程

和普通变量一样,对象之间也可以相互赋值。赋值运算符“=”可以用来将一个对象拷贝给另一个已经存在的对象。对象之间的赋值是将成员变量依次拷贝,而不是将整个对象的内存按位拷贝。

[举例] 对象之间的赋值:
  1. #include<iostream>
  2. usingnamespacestd;
  3. classDemo{
  4. private:
  5. inta;
  6. intb;
  7. public:
  8. Demo():a(0),b(0){}
  9. Demo(inta,intb):a(a),b(b){}
  10. voiddisplay(){cout<<a<<", "<<b<<endl;}
  11. };
  12. intmain(){
  13. Demoobj1,obj2(10,20);
  14. obj1=obj2;//对象之间的赋值
  15. obj1.display();
  16. return0;
  17. }
运行结果:
10, 20

一般情况下,默认的“=”就能满足我们的需求,但是当一个类中包含指针类型的成员变量时,可能会带来问题。请看下面的代码:
  1. #include<iostream>
  2. usingnamespacestd;
  3. classBook{
  4. private:
  5. doubleprice;//书的价格
  6. int*bookmark;//书签
  7. intnum;//书签的数量
  8. public:
  9. Book():price(0.0),bookmark(NULL),num(0){}
  10. Book(double,int*,int);
  11. voidsetBookmark(int,int);//修改书签
  12. voiddisplay();
  13. };
  14. Book::Book(doubleprice,int*bm,intnum):price(price),num(num){
  15. int*bmTemp=newint[num];
  16. for(inti=0;i<num;i++){
  17. bmTemp[i]=bm[i];
  18. }
  19. this->bookmark=bmTemp;
  20. }
  21. voidBook::setBookmark(intpage,intindex){
  22. if(index>=num-1){
  23. cout<<"Out of bound!"<<endl;
  24. }else{
  25. bookmark[index]=page;
  26. }
  27. }
  28. voidBook::display(){
  29. cout<<"price: "<<price<<endl;
  30. cout<<"bookmarks: ";
  31. for(inti=0;i<num;i++){
  32. if(i==num-1){
  33. cout<<bookmark[i]<<endl;
  34. }else{
  35. cout<<bookmark[i]<<", ";
  36. }
  37. }
  38. }
  39. intmain(){
  40. intbookmark[]={1,49,56,290};
  41. Bookjava,cpp(68.5,bookmark,4);
  42. cpp.display();
  43. java=cpp;//对象之间赋值
  44. java.setBookmark(100,2);
  45. cpp.display();
  46. return0;
  47. }
运行结果:
price: 68.5
bookmarks: 1, 49, 56, 290
price: 68.5
bookmarks: 1, 49, 100, 290

这段代码定义了一个 Book 类,表示一本书,书有价格,也有书签。书签是我们所标记的页码,这些页码中往往包含重要的知识点,记录下这些页码能够方便以后查阅。书签可以有多个,所以需要将它放在 int 型的数组中。setBookmark() 函数用来修改某个书签,display() 函数用来展示书签和价格。

Book 类的构造函数中不是直接接收参数的值,而是根据参数所指向的数组,再创建一个新的数组。这样做的好处是对象有属于自己的数组,在其他地方修改实参所指向的数组不会影响该数组,能够很好的隔离。

在 main() 函数中,我们创建了两个对象 java 和 cpp,并用 cpp 给 java 赋值。两次调用 display() 的结果不同表明,调用 java 对象的 setBookmark( ) 函数影响到了 cpp 对象。这是因为,执行java = cpp;语句时会将 cpp.bookmark 的值复制给 java.bookmark,不同对象的成员变量指向同一个数组,当然会相互影响。

要解决这个问题,就需要重载赋值运算符,如下所示:
  1. Book&Book::operator=(constBook&b){
  2. if(this!=&b){
  3. this->price=b.price;
  4. this->num=b.num;
  5. //为bookmark赋值
  6. int*bmTemp=newint[b.num];
  7. for(inti=0;i<b.num;i++){
  8. bmTemp[i]=b.bookmark[i];
  9. }
  10. this->bookmark=bmTemp;
  11. }
  12. return*this;
  13. }
将这个函数放入 Book 类中,再执行java = cpp;语句时,会转换为:java.operator=(cpp);在函数体中,this 就指向 java 对象。这样 java 对象也会拥有属于自己的数组,两个对象之间不会再相会影响。

可以发现,重载赋值运算符时,函数的参数和返回值类型都必须是对象的引用。以 Book 类为例来说,赋值运算符重载函数一般有两种原型:Book & operator=( Book &b ); Book & operator=( const Book &b );返回值和参数都是 Book 类对象的引用。下面一种原型则规定在赋值时不能修改原来的对象。

赋值运算符重载函数除了能有对象引用这样的参数之外,也能有其它参数。但是其它参数必须给出默认值。如下所示:Book & operator=(const Book &b, a = 10);
上一篇:武汉C++培训:重载++和--(自增自减运算符)
下一篇:武汉C++培训:重载new和delete运算符
选择城市和中心
贵州省

广西省

海南省