调用析构函数时的循环依赖性

时间:2014-06-13 05:05:39

标签: .net dependencies c++-cli destructor circular-dependency

我有以下架构,并且由于继承,当在类上调用destructors时,它会导致循环依赖。

namespace IntOp
{
    ref class PwItem;
    ref class PwTag;

public ref class PwItem
{
    public:
      PwItem(void* arg1, <sometype>arg2, unsigned __int64 arg3);
      {
          // some constructor work
      }
      virtual ~PwItem(){};
      static PwItem^ PwItem::CreateItem(void* arg1, <sometype>arg2, unsigned __int64 arg3) 
     {
        if(arg2 is of type PTag)
        {  //  PTag = gcnew PwTag(arg1, arg2, arg3);
           //  return PTag;
         return gcnew PwTag(arg1, arg2, arg3);
        }
        else if(arg2 is of type PFile)
        {    //PFile = gcnew PwTag(arg1, arg2, arg3);
            // return PFile;
         return gcnew PwFile(arg1, arg2, arg3);
        }
        return gcnew PwItem(arg1, arg2, arg3);
     }

   private : 

     //PwTag^ PTag;
   //  PwFile^ PFile;  //Another type with PwItem as Base constructor
 }


public ref class PwTag : PwItem
{
    public:
    PwTag(void* arg1, <sometype>arg2, unsigned __int64 arg3) : PwItem (void* arg1, <sometype>arg2, unsigned __int64 arg3) {};
   virtual ~PwTag();
}}

所以在这里,当我想在PwItem上调用删除时,它会释放PwItem的实例化,然后由于继承,PwTag调用destructorPwItem上,整个事情不断重演。

如何解决此问题?确实需要调用destructor来释放类对象中的一些东西。

编辑:添加了调用代码

myServer srv = new myServer();
srv.connect();
while(true)
{
    PwItem ^item = srv.GetItem(<some string>); //This will invoke the GetItem function, which will call createItem()
    System.Threading.Thread.Sleep(200);
}

实际的GetItem()函数

PwItem^ myServer::GetItem(<some string>)
{

    // do some work, nothing new being instantiated etc. just arguments 1, 2 and 3, which do not cause leaks
    return gcnew PwItem::CreateItem(arg1, arg2, arg3);
   // Tried instantiating a PwItem pi; return pi.CreateItem(arg1, arg2, arg3); as well. No luck
   // Bypassed PwItem entirely, and based on arg2, called return gcnew PwTag(arg1, arg2, arg3); as well, no luck
   // Tried PwItem pi, ^tempPwItem; tempPwItem = pi.CreateItem(arg1, arg2, arg3); return tempPwItem; No luck
}

1 个答案:

答案 0 :(得分:0)

我相信你正在努力创建一个工厂。但一个相当不寻常的工厂。您说您的基类根据请求的对象类型创建子类实例。但是你的代码正在做其他事情。 你每个孩子班有1个实例吗?此外,对于每个子类,您是否将其对象保留在基类(PwItem)中? 此外,没有在CreateItem方法中提到的位置,您需要哪个子实例! 让我们说一个PwXYZ子类出现了,那么你的代码是什么? 我看到的一个错误是你在静态函数中发送一个非静态的PwTag实例。

基类中所需要的只是一个STATIC CreateInstance方法,该方法将获取所请求对象的类型并返回该对象。不需要在基类中保留任何子类对象。

 //You can have an ENUM >>> enum ItemType { PwTag,... so on};
  static PwItem* PwItem::CreateItem(ItemType type){
  //check which type of object is requested and simply return the instance      
}

此外,您的基类应该有一个VIRTUAL(公共)析构函数。由于您要为子类发送Base引用,如果您尝试删除它,将导致内存泄漏(删除具有base&#39; s引用的子对象),因为不会调用child的析构函数

所以,现在你的基类就是

...

 public:
  PwItem();
  virtual ~PwItem(){};
  static PwItem^ PwItem::CreateItem(ItemType type) 
 {
    //switch cases OR IFs whatever you like...
    //return instance of the object requested
 }
...

希望这有帮助。

相关问题