动网论坛,站长建站首选,国内使用量最多的论坛软件 动网论坛官方技术讨论区 站长工具 申请属于您自己的免费论坛
首页 | 新闻资讯 | 网站运营 | 网络编程 | 数据库 | 服务器 | 网页设计 | 图像媒体 | 网络应用 | 搜索优化 | 资源下载 | 动网主机
    本站内  互联网 ASP论坛  ASP.Net论坛  PHP论坛
   .Net → 阅读文章

 C++/CLI思辨录之拷贝构造函数

作者来源: 
阅读 1602 人次 , 2006-4-25 14:59:00 


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

#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("%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("%s\n",_name);
  }
};

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

  希望上面所述能够帮助读者理解拷贝构造函数及其使用场所。
  
 
 收藏本文  打印本文  论坛讨论  关闭窗口
· 上一篇:C++/CLR泛型与C++模板之间的对比
· 下一篇:也谈制作系统托盘程序
· 通过事例学习.net的WebForms技术(二)
· 强化DataGrid Web 控件的编辑接口
· 邮件发送测试--Codebehind
· OO,OO以后,及其极限(1)
· ASP.NET读取POP3邮件的操作


关于本站 | 联系我们 | 业务合作 | 客户案例 | 诚聘英才 | 广告合作 | 收藏本站
海口动网先锋网络科技有限公司版权所有
Copyright © 2000 - 2006 Cndw.Com
中华人民共和国电信与信息服务业务经营许可证编号 琼 ICP 020077