This question already has answers here:
How can free Interface implemented class?
(2个答案)
6年前关闭。
我之前打开过类似的主题,但是在尝试释放类实例时,我没有明确的错误原因“错误的指针操作”。现在我已经知道了原因,因此我打开一个新主题来揭示问题。
因此,导致此错误的原因是在实例化类ChatClient并将类本身的实例(TChatManager)作为参数传递时。该问题可能与对接口的TChatManager类的实现有关。
接口:
TChatManager类:
TChatClient类:
主要:
任何人都可以解释我实施的不好吗?谢谢。
注意:类不完整,我删除了释放对象等的一些方法。
问候。
您的代码正在销毁具有非零
OP代码无法固定,应该重新设计,因为在当前形式下,
(2个答案)
6年前关闭。
我之前打开过类似的主题,但是在尝试释放类实例时,我没有明确的错误原因“错误的指针操作”。现在我已经知道了原因,因此我打开一个新主题来揭示问题。
因此,导致此错误的原因是在实例化类ChatClient并将类本身的实例(TChatManager)作为参数传递时。该问题可能与对接口的TChatManager类的实现有关。
接口:
Type
// An interface definition
IMessageEvents = Interface(IInterface)
['{BD27EFC6-CC9A-437A-A8B8-16F722518836}']
Procedure messageReceived(messageData: String);
End;
TChatManager类:
Type
TChatManager = Class(TInterfacedObject, IMessageEvents)
Private
cChatClient: TChatClient;
Protected
Procedure messageReceived(messageData: String); Overload;
Public
Constructor Create; Overload;
Destructor Destroy; Override;
End;
Implementation
Constructor TChatManager.Create;
Begin
Inherited Create;
self.cChatClient := TChatClient.Create(self); // self class instance as parameter
End;
Procedure TChatManager.messageReceived(messageData: String);
Begin
End;
Destructor TChatManager.Destroy;
Begin
Inherited Destroy;
End;
TChatClient类:
Type
TChatClient = Class(TObject)
Private
iMsgEvents: IMessageEvents;
Protected
Public
Constructor Create(iMsgEvents: IMessageEvents); Overload;
Destructor Destroy; Override;
End;
Implementation
Constructor TChatClient.Create(iMsgEvents: IMessageEvents);
Begin
Inherited Create;
self.iMsgEvents := iMsgEvents;
End;
Destructor TChatClient.Destroy;
Begin
Inherited Destroy;
End;
主要:
cChatManager: TChatManager;
self.cChatManager := TChatManager.Create;
self.cChatManager.Free; // Failed
任何人都可以解释我实施的不好吗?谢谢。
注意:类不完整,我删除了释放对象等的一些方法。
问候。
最佳答案
问题的答案是使用以下TInterfacedObject
方法:
procedure TInterfacedObject.BeforeDestruction;
begin
if RefCount <> 0 then
Error(reInvalidPtr);
end;
您的代码正在销毁具有非零
TChatManager
字段的RefCount
实例,因为它由TChatClient
实例引用。OP代码无法固定,应该重新设计,因为在当前形式下,
TChatManager
实例应在TChatClient
析构函数中销毁(通过设置iMsgEvents:= nil
),这很奇怪! :)10-08 12:20