【原】关于C++中的拷贝构造和赋值重载的理解

这阵子在学习C++ Primer ,关于书中的复制构造函数不是很理解。

上网上查了一些,加上书上的,在这里做一些总结:

首先考虑C++中的初始化形式:有直接初始化和复制初始化,例如:

  int val(1024); //直接初始化

  int val=1024 ; //复制初始化

此处使用=来初始化,但是C++中初始化和赋值是两种不同的操作,具体参考下面的关于赋值重载的说明。

再回过来看复制构造函数,上面说的复制初始化总是调用复制构造函数。复制初始化首先使用指定的构造函数创建一个临时对象,然后再用复制构造函数将那个临时对象复制到正在创建的对象中。

总之:拷贝构造函数的功能是用一个已存在的对象去构造并初始化另一个新创建的对象。它既要构造一个新的对象,又要把已有的对象内容赋给新对象,其次由于拷贝构造函数要把一个已有的对象的相关内容赋值给新对象,所以需要该类对象的引用做做参数。例如:用一个对象初始化另一个对象的时候:A(const A& a);

下面再看看重载赋值:

需要先了解重载操作符。重载赋值接受单个的形参,且该形参是同一个类类型对象。右操作符一般作为const引用传递。什么时候调用赋值构造?当显式使用 “=”

拷贝函数本质是一个构造函数,只不过他是依据一个已存在的对象(对象内容)来构造另一个对象。这过程中会依次调用父类的构造函数,正如一般构造函数的行为那样。
而赋值运算符,本质是使一个已存在的对象内容与目的对象的内容相同。就是说被赋值的对象已经有内容了。但对于拷贝函数,这时候对象是还没有内容的。

下面是网上的一个例子,我觉得很不错:

C++代码
  1. /*  
  2. language:c++  
  3. author:longsy  
  4. file:rectangle.h  
  5. */  
  6. namespace longsy {   
  7.     class Rectangle {   
  8.         int width;   
  9.         int height;   
  10.     public:   
  11.                  //带默认实参的默认构造函数   
  12.         Rectangle(int w=0, int h=0);   
  13.             //复制构造函数   
  14.                   Rectangle(const Rectangle & rect);   
  15.                   //赋值操作符   
  16.         Rectangle& operator=(const Rectangle &rect);   
  17.         //析构造函数   
  18.                   ~Rectangle();   
  19.                
  20.         void Draw();   
  21.     };   
  22. }  
    1. /*  
    2. language:c++  
    3. author:longsy  
    4. file:rectangle.cpp  
    5. */  
    6. #include "rectangle.h"   
    7. using namespace longsy;   
    8.   
    9. #include <iostream>   
    10.   
    11. Rectangle::Rectangle(int w,int h) : width(w),height(h)    
    12. {   
    13.     std::cout << "Rectangle(int w,int h)" << std::endl;   
    14. }   
    15. Rectangle::Rectangle(const Rectangle &rect)    
    16. {   
    17.     this->width = rect.width;   
    18.     this->height = rect.height;   
    19.     std::cout << "Rectangle(const Rectangle &rect)" <<std::endl;   
    20. }   
    21. Rectangle& Rectangle::operator=(const Rectangle &rect)   
    22. {   
    23.     this->width = rect.width;   
    24.     this->height = rect.height;   
    25.     std::cout << "operator=(const Rectangle &rect)" << std::endl;   
    26.     return *this;   
    27. }   
    28. Rectangle::~Rectangle()   
    29. {   
    30.     this->width = 0;   
    31.     this->height = 0;   
    32.     std::cout << "~Rectangle()" << std::endl;      
    33. }   
    34.   
    35. void Rectangle::Draw()   
    36. {   
    37.     std::cout << "Draw the rectangle,width:" << this->width \   
    38. << ",height:" << height <<std::endl;   
    39. }  

    测试文件,test.cpp 
    C++代码
    1. /*  
    2. language:c++  
    3. author:longsy  
    4. file:test.cpp  
    5. */  
    6. #include "rectangle.h"   
    7. using namespace longsy;   
    8.   
    9. int main()   
    10. {   
    11.     Rectangle rect; //调用默认构造函数   
    12.     rect.Draw();   
    13.        
    14.     Rectangle rect1(1,1); //Rectangle(int w,int h)   
    15.     rect1.Draw();   
    16.        
    17.     Rectangle rect2 = rect1;//调用复制构造函数   
    18.     rect2.Draw();   
    19.        
    20.     Rectangle rect3(2,2); //Rectangle(int w,int h)   
    21.     rect3.Draw();   
    22.     rect3 = rect1; //调用赋值操作符   
    23.     rect3.Draw();   
    24.        
    25.     return (0); //调用析构函数   
    26. }   
    27. /*  
    28. 运行结果:  
    29. Rectangle(int w,int h)  
    30. Draw the rectangle,width:0,height:0  
    31. Rectangle(int w,int h)  
    32. Draw the rectangle,width:1,height:1  
    33. Rectangle(const Rectangle &rect)  
    34. Draw the rectangle,width:1,height:1  
    35. Rectangle(int w,int h)  
    36. Draw the rectangle,width:2,height:2  
    37. operator=(const Rectangle &rect)  
    38. Draw the rectangle,width:1,height:1  
    39. ~Rectangle()  
    40. ~Rectangle()  
    41. ~Rectangle()  
    42. ~Rectangle()  
    43. */  

    posted on 2011-03-09 17:53  鲁大山  阅读(1859)  评论(0编辑  收藏  举报

    导航