C++学习笔记(8)----闲聊“拷贝构造函数”

来源:互联网 发布:mac屏蔽广告插件 编辑:程序博客网 时间:2024/06/14 12:16

What is it?

拷贝构造函数,是一种特殊的构造函数,它由编译器调用来完成一些基于同一类的其他对象的构建及初始化。其唯一的参数(对象的引用)是不可变的(const类型)。此函数经常用在函数调用时用户定义类型的值传递及返回。拷贝构造函数要调用基类的拷贝构造函数和成员函数。如果可以的话,它将用常量方式调用,另外,也可以用非常量方式调用。

When use it?

 在C++中,下面三种对象需要调用拷贝构造函数(有时也称“复制构造函数”):

  1) 一个对象作为函数参数,以值传递的方式传入函数体;
  2) 一个对象作为函数返回值,以值传递的方式从函数返回;
  3) 一个对象用于给另外一个对象进行初始化(常称为复制初始化);
  如果在前两种情况不使用拷贝构造函数的时候,就会导致一个指针指向已经被删除的内存空间。对于第三种情况来说,初始化和赋值的不同含义是拷贝构造函数调用的原因。事实上,拷贝构造函数是由普通构造函数和赋值操作符共同实现的描述拷贝构造函数和赋值运算符的异同的参考资料有很多。

 通常的原则是:①对于凡是包含动态分配成员或包含指针成员的类都应该提供拷贝构造函数;②在提供拷贝构造函数的同时,还应该考虑重载"="赋值操作符号。

 拷贝构造函数必须以引用的形式传递(参数为引用值)其原因如下:当一个对象以传递值的方式传一个函数的时候,拷贝构造函数自动的被调用来生成函数中的对象。如果一个对象是被传入自己的拷贝构造函数,它的拷贝构造函数将会被调用来拷贝这个对象这样复制才可以传入它自己的拷贝构造函数,这会导致无限循环直至栈溢出(Stack Overflow)。除了当对象传入函数的时候被隐式调用以外,拷贝构造函数在对象被函数返回的时候也同样的被调用。

重载的示例

  类定义变为:
  class CExample
  {
  public:
  CExample(){pBuffer=NULL; nSize=0;}
  ~CExample(){delete pBuffer;}
  CExample(const CExample&); //拷贝构造函数
  CExample& operator = (const CExample&); //赋值符重载
  void Init(int n){ pBuffer=new char[n]; nSize=n;}
  private:
  char *pBuffer; //类的对象中包含指针,指向动态分配的内存资源
  int nSize;
  };
  //赋值操作符重载
  CExample& CExample::operator = (const CExample& RightSides)
  {
  if (this == &RightSides) // 如果自己给自己赋值则直接返回
  {return *this;}
  nSize=RightSides.nSize;//复制常规成员
  char *temp=new char[nSize]; //复制指针指向的内容
  memcpy(temp,RightSides.pBuffer,nSize*sizeof(char));
  delete []pBuffer;//删除原指针指向内容(将删除操作放在后面,避免X=X特殊情况下,内容的丢失)
  pBuffer=temp;//建立新指向
  return *this;
  }

重载的注意事宜

  拷贝构造函数和赋值函数的功能是相同的,为了不造成重复代码,拷贝构造函数实现如下:
  CExample::CExample(const CExample& RightSides)
  {
  *this=RightSides; //调用重载后的"="
  }

原创粉丝点击