我有以下架构,并且由于继承,当在类上调用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
调用destructor
在PwItem
上,整个事情不断重演。
如何解决此问题?确实需要调用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
}
答案 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
}
...
希望这有帮助。