C++构造与析构
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++构造与析构的更多相关文章
- C++浅析——继承类中构造和析构顺序
先看测试代码,CTEST 继承自CBase,并包含一个CMember成员对象: static int nIndex = 1; class CMember { public: CMember() { p ...
- Effective C++ -----条款09:绝不在构造和析构过程中调用virtual函数
在构造和析构期间不要调用virtual函数,因为这类调用从不下降至derived class(比起当前执行构造函数和析构函数的那层).
- 【09】绝不在构造和析构过程中调用virtual方法
1.绝不在构造和析构过程中调用virtual方法,为啥? 原因很简单,对于前者,这种情况下,子类专有成分还没有构造,对于后者,子类专有成分已经销毁,因此调用的并不是子类重写的方法,这不是程序员所期望的 ...
- C++不能中断构造函数来拒绝产生对象(在构造和析构中抛出异常)
这是我的感觉,具体需要研究一下- 找到一篇文章:在构造和析构中抛出异常 测试验证在类构造和析构中抛出异常, 是否会调用该类析构. 如果在一个类成员函数中抛异常, 可以进入该类的析构函数. /// @f ...
- STL——空间配置器(构造和析构基本工具)
以STL的运用角度而言,空间配置器是最不需要介绍的东西,它总是隐藏在一切组件(更具体地说是指容器,container)的背后,默默工作,默默付出.但若以STL的实现角度而言,第一个需要介绍的就是空间配 ...
- 魔法方法:构造和析构 - 零基础入门学习Python041
魔法方法:构造和析构 让编程改变世界 Change the world by program 构造和析构 什么是魔法方法呢?我们来系统总结下: - 魔法方法总是被双下划线包围,例如__init__ - ...
- 再探Delphi2010 Class的构造和析构顺序
发了上一篇博客.盒子上有朋友认为Class的构造和析构延迟加载.是在Unit的初始化后调用的Class的构造.在Unit的反初始化前调用的Class的析构函数. 为了证明一下我又做了个试验 unit ...
- Effective C++_笔记_条款09_绝不在构造和析构过程中调用virtual函数
(整理自Effctive C++,转载请注明.整理者:华科小涛@http://www.cnblogs.com/hust-ghtao/) 为方便采用书上的例子,先提出问题,在说解决方案. 1 问题 1: ...
- STL—对象的构造与析构
STL内存空间的配置/释放与对象内容的构造/析构,是分开进行的. 对象的构造.析构 对象的构造由construct函数完成,该函数内部调用定位new运算符,在指定的内存位置构造对象 ...
- C++反汇编第二讲,不同作用域下的构造和析构的识别
C++反汇编第二讲,不同作用域下的构造和析构的识别 目录大纲: 1.全局(静态)对象的识别,(全局静态全局一样的,都是编译期间检查,所以当做全局对象看即可.) 1.1 探究本质,理解构造和析构的生成, ...
随机推荐
- 解决xcode7.3的一个bug的方法
我今天遇到个bug,就是pod后,居然系统自带的提示语全部没有了,连NSString都要自己拼写,后来百度了,但是都没有解决,然后综合了一下,解决了. 方法: 首先点击桌面 找到前往-->然后选 ...
- Web.config 文件中的 system.webServer
Web.config 文件中的 system.webServer 节用于指定适用于 Web 应用程序的 IIS 7.0 设置.system.WebServer 是 configuration 节的子级 ...
- 关于在框架中使用curl的思考,以及,curl其实很好用
初步猜想: 在接触到框架文档的第一阶段时,会觉得控制器调用模型就是一件很简单的事,tp中用D方法或者M方法来实例化模型,laravel中用命名空间来加载模型,CI中用$this->load-&g ...
- fiddler还是浏览器的问题
当我在浏览器里输入http://localhost/infomanage/price?cityid=1&cateid=246&timer=3 后端接收的参数是timer的时候,浏览器会 ...
- Linux安装Firefly
1.安装一些必要的东东 yum install -y gcc zlib zlib-devel lrzsz openssl openssl-devel python-devel mysql-devel ...
- python 访问数据库
commit() 提交rollback() 回滚 cursor用来执行命令的方法:callproc(self, procname, args):用来执行存储过程,接收的参数为存储过程名和参数列表,返回 ...
- css基础和心得(二)
css中的某些样式是具有继承性的.它允许样式不仅应用于某个特定html标签元素 而且应用于其后代.如: p{color:red;} <p>dsffd<spans>sdfasd ...
- js数组操作-找出一组按不同顺序排列的字符串的数组元素
从一组数组中找出一组按不同顺序排列的字符串的数组元素将字符串转换成数组后再对数组进行 sort 排序,abcd 和 bdca 使用 sort 排序后会变成 abcd,将拍好序的字符串作为对象的 key ...
- Hbase压力测试
PerformanceEvaluation是HBase自带的性能测试工具,该工具提供了顺序读写.随机读写.扫描等性能测试功能.本文简要介绍HBase PerformanceEvaluation的使用方 ...
- Python学习笔记——进阶篇【第九周】———线程、进程、协程篇(队列Queue和生产者消费者模型)
Python之路,进程.线程.协程篇 本节内容 进程.与线程区别 cpu运行原理 python GIL全局解释器锁 线程 语法 join 线程锁之Lock\Rlock\信号量 将线程变为守护进程 Ev ...