游戏开发论坛

 找回密码
 立即注册
搜索
楼主: bluebaby9811

如何保证一个对象最先构造,最后析构?

[复制链接]

7

主题

48

帖子

128

积分

注册会员

Rank: 2

积分
128
QQ
发表于 2009-11-19 12:07:00 | 显示全部楼层

Re:如何保证一个对象最先构造,最后析构?

~CSupporter()
  {
   printf("~CSupporter()\n");
   if(NULL!=m_pUS&&0==--m_pUS->m_UserCount)
   {
    delete m_pUS;
    m_pUS=NULL;
   }
  }
呵呵,你自己可以看看,这个类释放了多少次,还有,在什么时候释放的吧,所以你这设计根本就没有什么用处啊,你如果想用singleton来做,跟本不需要那个辅助结构。

45

主题

157

帖子

169

积分

注册会员

Rank: 2

积分
169
QQ
 楼主| 发表于 2009-11-19 12:13:00 | 显示全部楼层

Re: 如何保证一个对象最先构造,最后析构?

bluebaby9811: 如何保证一个对象最先构造,最后析构?

这是我在百度知道上的问题:
    程序中有一个对象是其它对象必需依赖的,如何保证...


新发现,程序如下:
//支持者
class CSupporter
{
public:
  CSupporter()
  {
   if(NULL==m_pData)m_pData=new Data;
   else m_pData->AddUser();
  }
  ~CSupporter()
  {
   if(NULL!=m_pData&&0==m_pData->DecUser())
   {
    delete m_pData;
    m_pData=NULL;
   }
  }
  CSupporter(const CSupporter& src){if(NULL!=m_pData)m_pData->AddUser();}
  CSupporter& operator=(const CSupporter& src){return *this;}
  
private:
  struct Data
  {
   long m_UserCount;
   //这里可以添加其它数据

   Data():m_UserCount(1){cout<<"构造支持者"<<(unsigned long)this<<"!"<<endl;}
   ~Data(){cout<<"析构支持者"<<(unsigned long)this<<"!"<<endl;}
   void AddUser(){++m_UserCount;}
   long DecUser(){return --m_UserCount;}
  };
  static Data* m_pData;
};
CSupporter:ata* CSupporter::m_pData=NULL;

class CA
{
public:
  CA(){cout<<"构造CA对象"<<(unsigned long)this<<"!"<<endl;}
  ~CA(){cout<<"析构CA对象"<<(unsigned long)this<<"!"<<endl;}
private:
  CSupporter m_Supporter;
};
class CB
{
public:
  CB(){cout<<"构造CB对象"<<(unsigned long)this<<"!"<<endl;}
  ~CB(){cout<<"析构CB对象"<<(unsigned long)this<<"!"<<endl;}
private:
  CSupporter m_Supporter;
};
class CC
{
public:
  CC(){cout<<"构造CC对象"<<(unsigned long)this<<"!"<<endl;}
  ~CC(){cout<<"析构CC对象"<<(unsigned long)this<<"!"<<endl;}
private:
  CSupporter m_Supporter;
};
class CD
{
public:
  CD(){cout<<"构造CD对象"<<(unsigned long)this<<"!"<<endl;}
  ~CD(){cout<<"析构CD对象"<<(unsigned long)this<<"!"<<endl;}
private:
  CSupporter m_Supporter;
};

//测试用例
int main()
{
CA a1, a2;
CB b1, b2;
CD d1, d2;
CC c1, c2;
return 0;
}

    因为构造用户类对象时,CSupporter类的构造函数也会被调用,所以用户类的构造函数中就不需要CSupporter类对象的引用作为其参数了。当构造第一个用户类对象时,CSupporter类对象就会正确构造并使引用计数为1,接下来构造其它用户类对象时,只是使引用计数增加,这也是符合原语义的,增加一个用户类对象,就增加一份引用,减少一个用户类对象,就减少一份引用,这很好理解吧。我想这正是C++的高明之处吧!尽量使程序意思与原语义相符。运行结果如下:

45

主题

157

帖子

169

积分

注册会员

Rank: 2

积分
169
QQ
 楼主| 发表于 2009-11-19 12:27:00 | 显示全部楼层

Re: Re:如何保证一个对象最先构造,最后析构?

jianxin: Re:如何保证一个对象最先构造,最后析构?

~CSupporter()
  {
   printf("~CSupporter()\n");
   if(NULL!=m_pUS&&0==--m_pUS-&...


    当然了,你有多少份引用,这个类的析构函数就会被调用多少次,但除了引用计数为0的那次外,其它都只是让引用计数减1,意思就是你的引用少了一份了。所以真正析构对象的只有一次,就是当引用计数为0时的那次,已没有谁在用我了吧,那么我可以消失了吧。呵呵,大概就这意思吧!
    如果用singleton来做,当我构造用户类时,我不确定singleton是否已实例化了。所以这不太把稳。

7

主题

48

帖子

128

积分

注册会员

Rank: 2

积分
128
QQ
发表于 2009-11-19 12:42:00 | 显示全部楼层

Re:如何保证一个对象最先构造,最后析构?

CSupporter()
  {
   if(NULL==mpThis)mpThis=This;
   else mpThis->AddUser();
  }

7

主题

48

帖子

128

积分

注册会员

Rank: 2

积分
128
QQ
发表于 2009-11-19 12:43:00 | 显示全部楼层

Re:如何保证一个对象最先构造,最后析构?

这样一定会构造啊

3

主题

30

帖子

34

积分

注册会员

Rank: 2

积分
34
发表于 2009-11-19 13:25:00 | 显示全部楼层

Re:如何保证一个对象最先构造,最后析构?

用动态构造,这样你想它什么时候构造就用new构造,你想什么时候析构就自己用delete析构。

30

主题

422

帖子

433

积分

中级会员

Rank: 3Rank: 3

积分
433
发表于 2009-11-19 14:42:00 | 显示全部楼层

Re: Re: Re:如何保证一个对象最先构造,最后析构?

bluebaby9811: Re: Re:如何保证一个对象最先构造,最后析构?
    如果用singleton来做,当我构造用户类时,我不确定singleton是否已实例化了。所以这不太把稳。

template<t>
class Singleton
{
public:
  static t &GetInstance()
  {
    static t s_;
    return s_;
  }
};

class MyClass : public Singleton<MyClass>
{
public:
   // ...
};

无论何处第一次使用MyClass::GetInstance()必然给你一个有效的对象。

然而其实这样做仍然有问题。假如你的某全局对象生命期比这个Singleton的函数内对象还长(虽然不太容易这么写,但这是有可能的),那么当你这个对象析构时做访问MyClass::GetInstance时将获得一个已经被析构了的对象。

45

主题

157

帖子

169

积分

注册会员

Rank: 2

积分
169
QQ
 楼主| 发表于 2009-11-19 15:08:00 | 显示全部楼层

Re: Re: Re: Re:如何保证一个对象最先构造,最后析构?

kaikai: Re: Re: Re:如何保证一个对象最先构造,最后析构?


template<t>
class Singleton
{
public:
  static t &GetInstance()
  {
    static t s...

是啊,你已经说了无论何处第一次使用MyClass::GetInstance()必然给你一个有效的对象,也可以理解为直到第一次调用MyClass::GetInstance()它才给你一个有效的对象,所以用来解决我们的问题有点勉强了。

45

主题

157

帖子

169

积分

注册会员

Rank: 2

积分
169
QQ
 楼主| 发表于 2009-11-19 15:14:00 | 显示全部楼层

Re: Re:如何保证一个对象最先构造,最后析构?

jianxin: Re:如何保证一个对象最先构造,最后析构?

CSupporter()
  {
   if(NULL==mpThis)mpThis=This;
   else mpThis->AddUser();
  }

不太理解。This是什么,mpThis又是什么,mpThis是不是那个助手类指针(也就是那个助手结构,在C++中结构也可以看成类),面This是不是想写成this指针,结果写错了。如果是这样的话就更不能理解了,它们是不同类型的指针,怎么能赋值呢?

45

主题

157

帖子

169

积分

注册会员

Rank: 2

积分
169
QQ
 楼主| 发表于 2009-11-19 15:20:00 | 显示全部楼层

Re: Re:如何保证一个对象最先构造,最后析构?

Snow_Ice11111: Re:如何保证一个对象最先构造,最后析构?

用动态构造,这样你想它什么时候构造就用new构造,你想什么时候析构就自己用delete析构。


呵呵,你这是C的思想,我们现在用C++了,就用C++的思想解决问题吧,而且什么都自己做的话,项目大了很容易出错的,所以我们要好好利用语言提供的特性把错误降到最低。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-6-1 11:48

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表