选择显示字体大小

c++/cli思辨录之拷贝构造函数


  虽然对象复制看上去很简单,然而如果你没有对其正确理解,可能会出现一些严重问题。默认情况下,复制对象会导致相应的所有成员的复制。如果你只有实例成员,这看上去是相当不错的。但是如果你的类中含有指向在堆中分配的对象时,情况会怎样呢?考虑下面的代码片断:

#include <stdio.h>
#include <string.h>
class person
{
 private:
  char* _name;
 public:
  person()
  {
   _name = new char[256];
  }
  void setname(const char* name)
  {
   if(strlen(name) + 1 < 256)
    strcpy(_name,name);
  }
  void printname()
  {
   printf("&#37;s\n",_name);
  }
 };
 int main()
 {
  // 创建对象的第一个实例并赋于名字为john
  person p1;
  p1.setname("john");
  p1.printname();
  //通过复制p1引用的对象创建另一个对象
  person p2(p1);
  p2.setname("alice");
  p2.printname();
  //现在再输出p1的名字
  p1.printname();
  scanf("q");
  return 0;
 }

  这里的类person有一个指向在堆上分配的字符数组的指针。当构造person对象时,它创建该字符数组并把它的位置存放到变量_name中。

  但是当你创建person 对象 p2 时,p2的成员用p1的成员初始化。因而,p1的 _name与p2的 _name指向相同的堆对象。如在上例中看到的,调用p2.setname将改变由这两个类共享的值。所以,当第二次调用p1.printname,打印结果是"alice"。

  所以,这不是我们复制对象所期望的结果,而且还会导致堆崩溃的问题。请再考虑某个函数删除了该数组而p1又要调用该函数的情况?下面,当p2调用printname时,它将尽量存取实际上不是在堆上的对象。这种情况下产生的结果往往是难以预料的。

  c++允许我们通过定义拷贝构造函数来克服这类问题。在我们每次通过复制另一个对象来初始化一个对象时,拷贝构造函数都被执行。你可以在拷贝构造函数中覆盖掉缺省的成员函数的复制行为。

  所以,我们的类person应该修改如下:

class person
{
 private:
  char* _name;
 public:
  person()
  {
   _name = new char[256];
  }
  // 这是拷贝构造函数。在此我们初始化一个新的数组,为person的实例所用
  person(person&)
  {
   _name = new char[256];
  }
  void setname(const char* name)
  {
   if(strlen(name) + 1 < 256)
    strcpy(_name,name);
  }
  void printname()
  {
   printf("&#37;s\n",_name);
  }
};

  这里类person中的拷贝构造函数保证了它初始化一个新的数组,为在复制时产生的每一个对象实例所用。这就避免了前面我们提到的问题。

  希望上面所述能够帮助读者理解拷贝构造函数及其使用场所。


 


关键字 本文所属关键字

相关 与本文相关文章

分类 所有文章关键字导航

源码编程相关

Java   Asp   PHP   .Net   XML   C/C++   CGI   VB   Jsp   J2ee   J2se   J2me   EJB   Servlet   Tomcat   Resin   Struts   Weblogic   Eclipse   ANT   GUI   JMS   Web servise   IDEA   Webphere   Hibernate   Spring   Jboss   Applet   Swing   Socket   Javamail   Perl   Ajax   P2P   安全   模式   框架   测试   开源   游戏

SQL数据库相关

My-SQL   Ms-SQL   Access   DB2   Oracle   Sybase   SQLserver   索引   存储过程   加密   数据库   分页   视图  

手机无线相关

3G   Wap   CDMA   GRPS   GSM   IVR   彩信   短信   无线   增值业务

网页设计制作相关

HTML   CSS   网页配色   网页特效   Javascript   VBscript   Dreamweaver   Frontpage   JS   Web   网站设计

网站建设推广相关

建站经验   网站优化   网站排名   推广   Alexa

操作系统/服务器相关

Windows XP   Windows 2000   Windows 2003   Windows Me   Windows 9.x   Linux   UNIX   注册表   操作系统   服务器   应用服务器

图形图像多媒体相关

Photoshop   Fireworks   Flash   Coreldraw   Illustrator   Freehand   Photoimpact   多媒体   图形图像

标准 网站致力的规范

Valid CSS!

无不良内容,无不良广告,无恶意代码

Valid XHTML 1.0 Transitional

creativecommons