首页
社区
课程
招聘
[注意]构造函数中调用构造函数的注意
发表于: 2015-4-14 21:39 5422

[注意]构造函数中调用构造函数的注意

2015-4-14 21:39
5422
此贴中提到了一种构造函数调用构造函数的方法:

http://bbs.pediy.com/showthread.php?p=1198340

低版本的C++中也可以顺利编译通过,我也十分喜欢这种方法,但是今天发现这种方法是有问题的。由于原主题已经锁定无法回复,故开新帖说明,请大家注意。

问题在于这种方式会造成成员变量的多次构造,但不对应多次析构,形成泄露。示例代码:

/*
 *  @file  : TestConstructorInConstructor.cpp
 *  @author: Shilyx
 *  @date  : 2015-04-14 21:24:01.706
 *  @note  : Generated by SlxTemplates
 */

#include <stdio.h>
#pragma warning(disable: 4786)
#include <iostream>
#include <string>

using namespace std;

class CMember
{
public:
    CMember()
    {
        cout << __FUNCTION__ << endl;
    }

    ~CMember()
    {
        cout << __FUNCTION__ << endl;
    }
};

class CTest
{
public:
    CTest()
    {
        this->CTest::CTest(0);
    }

    CTest(int n)
    {
        m_n = n;
    }

private:
    int m_n;
    CMember m_m;
};

int main(int argc, char *argv[])
{
    CTest t;
    return 0;
}


输出:

CMember::CMember
CMember::CMember
CMember::~CMember
请按任意键继续. . .

代码: TestConstructorInConstructor.zip

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 0
支持
分享
最新回复 (11)
雪    币: 144
活跃值: (38)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
我擦,以前没有注意,一直这么写代码的
2015-4-14 22:53
0
雪    币: 292
活跃值: (153)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
3
你的UrlSniffer不更新了吗?.......
2015-4-14 23:07
0
雪    币: 200
活跃值: (38)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
4
c++11之后,正确的方式是

CTest() : CTest(0)
    {
    }
2015-4-14 23:31
0
雪    币: 69
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
支持一下,
2015-4-14 23:50
0
雪    币: 163
活跃值: (1623)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
6
按照构造函数的顺序      基类构造函数->成员类构造函数->派生类构造函数,所以会有两次 成员类构造函数。一般不会本类的构造函数调用本类的构造函数,会提取到一个私有类成员函数中。
2015-4-14 23:58
0
雪    币: 209
活跃值: (143)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
有什么好的需求点吗
2015-4-15 09:14
0
雪    币: 2738
活跃值: (1077)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
8
this->CTest::CTest(0); 这是干什么用的?
创建一个类你可以这样 CTest test(0);
调用类成员你可以test(0);

this->CTest::CTest(0);我可以理解为手动的调用了CTest(0)?
那么既然你手动调用了CTest(0),就该手动调用this->CTest::~CTest(0); 进行析构

this->CTest::CTest(0);仅仅是调用了该函数,与创建对象没有半毛钱关系,
但是CMember的确多构造出来一次,那是因为C++将类成员的初始化汇编代码放到了所有构造函数里....

所以,这不是什么C++或者编译器的BUG,正确的代码是这样滴
  CTest()
    {
        this->CTest::CTest(0);
        this->CTest::~CTest(0);
    }

以上是我的个人理解,如有问题请指正~
2015-4-15 09:59
0
雪    币: 2592
活跃值: (37)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
不知道楼主为什么要这样写。…………………………
2015-4-15 10:13
0
雪    币: 209
活跃值: (143)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
为什么要调用其他构造函数?
有这种需求主要是因为存在多个构造函数的时候,多个函数间有一些公用的部分。常见的处理办法是将公用部分提取出来形成一个子函数由构造函数来调用。但是如果构造函数可以直接调用的话,就能更省事一些。C++11中也已经出现了构造函数调用其他构造函数的新语法,说明这种需求是确实存在的。这里提到的方法是一种兼容低版本c++的方法(价值所在,如果c++11普及了,这种方法也没用了),之前一直在用,最近才发现问题。

其实这个问题的原理也不复杂,大家都能明白。之前一直误用,也没有多想。
2015-4-15 10:22
0
雪    币: 2738
活跃值: (1077)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
11
还是没明白:构造函数调用其他构造函数,这是什么意思
我只在你的代码里看到同一个类调用了两次构造.

我认为显示调用构造本身就是有问题的

从0051719h处可以看出,显式调用构造函数会导致该类的所有成员变量被重新初始化

那么如下代码,m_n的值将会是0!
    CTest()
    {
		m_n = 10;
		this->CTest::CTest(0);
		cout << m_n;
    }
上传的附件:
2015-4-15 10:50
0
雪    币: 485
活跃值: (78)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
12
这完全就是一个成员变量的生命周期的问题。。。。
2015-4-18 22:27
0
游客
登录 | 注册 方可回帖
返回
//