C++语言构造函数与析构函数需要注意的地方。

构造

考虑以下定义

struct Node
{
char *name;
int value;
Node(char *name = "", int value = )
{
name = new char[strlen(name)+];
strcpy(name, name);
value = value;
}
}

声明两个对象

Node node1("child", ), node2(node1);

这行语句创建了两个对象node1,node2,其中node2是用node1的成员进行初始化,现在改变node2成员值

strcpy(node2.name, "parent");
node2.value = ;

打印对象的成员值如下

cout<<node1.name<<' '<<node1.value<<' '<<node2.name<<' '<<node2.value;

结果如下

parent  parent 

问题出在Node结构成员name是一个指针类型,如果结构定义中没有复制构造函数,则编译器使用默认的构造函数,此构造函数在复制值类型与复制指针类型时实现方法不同,复制指针类型时仅仅复制指针的内容(所指向的地址),所以node1和node2的name指针指向了同一个地址。

解决这个问题的办法是自定义一个复制构造函数

struct Node
{
char *name;
int value;
Node(char *name = "", int value = )
{
name = new char[strlen(name)+];
strcpy(name, name);
value = value;
}
Node(const Node& node)
{
name = new char[strlen(node.name) + ];
strcpy(name, node.name);
value = node.value;
}

当然,还有一个类似的问题就是

node2 = node1;

这句代码也是对成员进行浅表复制,解决的办法就是自定义赋值构造函数,仅给出代码片段

Node& operator=(const Node& node)
{
if(this != &n) { // no assignment to itself
if(name != )
delete [] name;  // 注意这里是 delete [],delete只是析构单个对象,而非字符数组
name = new char[strlen(node.name) + ];
strcpy(name, node.name);
value = node.value;
}
return *this;
}

析构

对于以上类型的对象,因为是值类型,所以如果是作为局部变量,当对象处于作用范围之外时将被销毁,被对象占用的内存也会得到释放。然而,这个对象占用的内存虽然被释放,但是跟这个对象相关联的内存则不一定被释放。如上面这个Node类型,有一个指向string的指针成员,因此,销毁Node类型对象时,对象的指针成员(name)所占用的内存被释放(32位机器上指针占用4byte),但是指针指向的string所占用的内存将会变得无法访问,这个内存也就无法被释放了。为了避免这个问题,类(结构)定义中需要包含析构函数。析构函数在对象被销毁时自动被调用,或者主动使用delete关键字调用析构函数。析构函数不接受参数,也不返回值。

在Node的定义增加一个析构函数

~Node()
{
if(name != )
delete [] name;
}

以上讨论了结构(struct)的构造函数和析构函数,对于类(class)的情况类似。

最新文章

  1. [转]IIS6.0迁移至IIS7.0
  2. TFS二次开发系列:二、TFS的安装
  3. mac平台多个php版本快速切换
  4. 移动端Viewport &amp; 使用rem来开发移动端网站
  5. [Ahoi2013]差异
  6. 关于debug时的一些操作
  7. 客户端的数据来源:QueryString, Form, Cookie Request[]与Request.Params[]
  8. 关于Java中return和finally谁先执行.
  9. Linux下使用sendmail发送邮件
  10. 为SRS流媒体服务器添加HLS加密功能(附源码)
  11. 【翻译】Ext JS 5的委托事件和手势
  12. TestNG监听器实现用例运行失败自动截图、重运行功能
  13. style,ng-style, ng-attr-style的对比
  14. Python:BeautifulSoup移除某些不需要的属性
  15. H5多媒体(用面向对象的方法控制视频、音频播放、暂停、延时暂停)
  16. sking
  17. 彻底解决Odoo8.0单时区应用中的时区问题
  18. 关于VS2013编辑器的问题
  19. PCA 原理
  20. .net core 填坑记之二目录问题(获取当前目录、创建目录)

热门文章

  1. json字符串中key值下划线命名转换为驼峰命名
  2. 使用ab对站点进行压力测试
  3. Sipdroid实现SIP(三): 消息接收处理
  4. js作用域详解
  5. Java版求1000以内的完全数
  6. C#模板打印功能-模板为WPS或Excel
  7. 判断iPhone设备是carplay和iPod的方法
  8. Java实现应用程序记住用户名、密码功能
  9. CSS3入门
  10. php入门 数据类型 运算符 语言结构语句 函数 类与面向对象