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)的情况类似。

C++构造与析构的更多相关文章

  1. C++浅析——继承类中构造和析构顺序

    先看测试代码,CTEST 继承自CBase,并包含一个CMember成员对象: static int nIndex = 1; class CMember { public: CMember() { p ...

  2. Effective C++ -----条款09:绝不在构造和析构过程中调用virtual函数

    在构造和析构期间不要调用virtual函数,因为这类调用从不下降至derived class(比起当前执行构造函数和析构函数的那层).

  3. 【09】绝不在构造和析构过程中调用virtual方法

    1.绝不在构造和析构过程中调用virtual方法,为啥? 原因很简单,对于前者,这种情况下,子类专有成分还没有构造,对于后者,子类专有成分已经销毁,因此调用的并不是子类重写的方法,这不是程序员所期望的 ...

  4. C++不能中断构造函数来拒绝产生对象(在构造和析构中抛出异常)

    这是我的感觉,具体需要研究一下- 找到一篇文章:在构造和析构中抛出异常 测试验证在类构造和析构中抛出异常, 是否会调用该类析构. 如果在一个类成员函数中抛异常, 可以进入该类的析构函数. /// @f ...

  5. STL——空间配置器(构造和析构基本工具)

    以STL的运用角度而言,空间配置器是最不需要介绍的东西,它总是隐藏在一切组件(更具体地说是指容器,container)的背后,默默工作,默默付出.但若以STL的实现角度而言,第一个需要介绍的就是空间配 ...

  6. 魔法方法:构造和析构 - 零基础入门学习Python041

    魔法方法:构造和析构 让编程改变世界 Change the world by program 构造和析构 什么是魔法方法呢?我们来系统总结下: - 魔法方法总是被双下划线包围,例如__init__ - ...

  7. 再探Delphi2010 Class的构造和析构顺序

    发了上一篇博客.盒子上有朋友认为Class的构造和析构延迟加载.是在Unit的初始化后调用的Class的构造.在Unit的反初始化前调用的Class的析构函数. 为了证明一下我又做了个试验 unit ...

  8. Effective C++_笔记_条款09_绝不在构造和析构过程中调用virtual函数

    (整理自Effctive C++,转载请注明.整理者:华科小涛@http://www.cnblogs.com/hust-ghtao/) 为方便采用书上的例子,先提出问题,在说解决方案. 1 问题 1: ...

  9. STL—对象的构造与析构

    STL内存空间的配置/释放与对象内容的构造/析构,是分开进行的.   对象的构造.析构         对象的构造由construct函数完成,该函数内部调用定位new运算符,在指定的内存位置构造对象 ...

  10. C++反汇编第二讲,不同作用域下的构造和析构的识别

    C++反汇编第二讲,不同作用域下的构造和析构的识别 目录大纲: 1.全局(静态)对象的识别,(全局静态全局一样的,都是编译期间检查,所以当做全局对象看即可.) 1.1 探究本质,理解构造和析构的生成, ...

随机推荐

  1. ie7,IE8不支持document.getElmentsByClassName的问题

    if (!document.getElementsByClassName) { document.getElementsByClassName = function(className, elemen ...

  2. c++ 常见问题之 vector 和数组

    初始化vector 对象: vector<T> v1 v1 为空vector vector<T> v2(v1) vector<T> v2 = v1 vector&l ...

  3. CODE[VS]-判断浮点数是否相等-浮点数处理-天梯青铜

    题目描述 Description 给出两个浮点数,请你判断这两个浮点数是否相等 输入描述 Input Description 输入仅一行,包含两个浮点数 输出描述 Output Description ...

  4. Scala Singleton对象

    Scala Object: scala没有静态的修饰符,例如Java中的static.但是Scala提供了Object类型,object下的成员都是静态的,比较像Java的静态类.不同在于Scala的 ...

  5. 【原创】RMQ - ST算法详解

    ST算法: ID数组下标: 1   2   3   4   5   6   7   8   9    ID数组元素: 5   7   3   1   4   8   2   9   8 1.ST算法作 ...

  6. hdu 3669 Cross the Wall(斜率优化DP)

    题目连接:hdu 3669 Cross the Wall 题意: 现在有一面无限大的墙,现在有n个人,每个人都能看成一个矩形,宽是w,高是h,现在这n个人要通过这面墙,现在只能让你挖k个洞,每个洞不能 ...

  7. nginx(1)

    下一篇:nginx(2) 一.engin X 市场的服务器非常的多,这里简单介绍几种常用的. Apache:源代码开放,跨平台,可移植,且支持的模块非常丰富,虽然在速度性能上不如其他轻量级的web服务 ...

  8. Qt出现常量有换行符的错误的解决方法

    可以使用 QString::fromLocal8Bit 来将本地字符编码转换为 Unicode 形式的 QString.

  9. github上前100的ios项目

    1. AFNetworking    作者是 NSHipster 的博主, iOS 开发界的大神级人物, 毕业于卡内基·梅隆大学, 开源了许多牛逼的项目, 这个便是其中之一, AFNetworking ...

  10. Jdk 1.8*安装并配置

     转载自:http://www.cnblogs.com/zlslch/p/5658399.html 简单说下,jdk1.8*的下载,见http://www.cnblogs.com/zlslch/p/5 ...