递归函数调用递归函数
来源:互联网 发布:郎酒2015销售额数据 编辑:程序博客网 时间:2024/05/15 00:22
题目如下:问下列代码的打印结果为0吗?
- #include <stdlib.h>
- #include <iostream>
- using namespace std;
- struct CLS
- {
- int m_i;
- CLS( int i ) : m_i(i){}
- CLS()
- {
- CLS(0);
- }
- };
- int main()
- {
- CLS obj;
- cout << obj.m_i << endl;
- system("PAUSE");
- return 0;
- }
代码奇怪的地方在于构造函数中调用了自己的另一个构造函数
我们知道,当定义一个对象时,会按顺序做2件事情:
1)分配好内存(非静态数据成员是未初始化的)
2)调用构造函数(构造函数的本意就是初始化非静态数据成员)
显然上面代码中,CLS obj;这里已经为obj分配了内存,然后调用默认构造函数,但是默认构造函数还未执行完,却调用了另一个构造函数,这样相当于产生了一个匿名的临时CLS对象,它调用CLS(int)构造函数,将这个匿名临时对象自己的数据成员m_i初始化为0;但是obj的数据成员并没有得到初始化。于是obj的m_i是未初始化的,因此其值也是不确定的
从这里,我们归纳如下:
1)在c++里,由于构造函数允许有默认参数,使得这种构造函数调用构造函数来重用代码的需求大为减少
2)如果仅仅为了一个构造函数重用另一个构造函数的代码,那么完全可以把构造函数中的公共部分抽取出来定义一个成员函数(推荐为private),然后在每个需要这个代码的构造函数中调用该函数即可
3)偶尔我们还是希望在类的构造函数里调用另一个构造函数,可以按下面方式做:
在构造函数里调用另一个构造函数的关键是让第二个构造函数在第一次分配好的内存上执行,而不是分配新的内存,这个可以用标准库的placement new做到:
先看看标准库中placement new的定义
- inline void *__cdecl operator new(size_t, void *_P)
- {
- return (_P);
- }
正确的方式:
- struct CLS
- {
- int m_i;
- CLS( int i ) : m_i(i){}
- CLS()
- {
- new (this)CLS(0);
- }
- };
另: 若构造函数调用自身,则会出现无限递归调用,是不允许的。
所以,在实际使用的时候,单纯的在构造函数中调用其它的构造函数,只是会产生一个临时的匿名变量。
如果仅仅是为了重用代码,可以把重用的代码封装成一个新的函数。
转载地址:http://blog.csdn.net/race604/article/details/6921678
- 递归函数调用递归函数
- 函数的递归调用
- 函数递归调用
- 函数递归调用
- 函数递归调用问题
- 函数递归调用详解
- 函数递归调用
- 函数的递归调用
- 函数调用与递归
- 函数的递归调用
- 函数调用--递归
- 函数的递归调用
- 函数的递归调用
- 函数的递归调用
- 函数的递归调用
- 函数的递归调用
- 函数调用(递归函数调用)底层机制
- 9.8 函数的递归调用
- P2P之UDP穿透NAT的原理与实现(附源代码)
- TubinePro.exe 中的 0x7c812a5b 处未处理的异常: Microsoft C++ 异常: 内存位置 0x0012dfa4 处的 _com_error。
- 算法——二叉树相关
- 怎样提高java程序的性能
- VM-linux中增加一块硬盘
- 递归函数调用递归函数
- [技巧]如何让Opera 在浏览淘宝时调用阿里旺旺聊天
- Asp.Net Excel 操作 类
- C语言和设计模式(工厂模式)
- MFC键值表
- button用法
- ajax实现分页
- 杭电hdu 1698 just a hook 线段树
- 执行make menuconfig错误