beta 的第四篇心得:一个释放后自动清空实例指针的类 (20分)

  • 主题发起人 主题发起人 beta
  • 开始时间 开始时间
beta前辈说得非常好。我记得曾经在一本C++的书上看到过一个“野指针”的概念,
我想这个“野指针”是不是和beta大虾说的意思是一样的。也就是指向内存区域的
指针还存在(门牌号码还在),但是内存中的数据已经被销毁了(房子被拆了),
于是访问这个指针,就会出现非法操作。是吧?
beta前辈在这里提出这个问题就是想让我们初学者注意这样的问题,因为这恐怕
也是一个很重要的问题,如果用的不好(也就是拆了房子还有门牌号),很容易出错
的,而且找这样的错误也会花不少的时间。于是beta前辈就想能不能用一种方法,简单
到调用free就可以避免这样的情况发生。
真的很感谢beta前辈的教诲,我等受益匪浅!
我有一个菜鸟级的问题,不知可不可以问问beta前辈,指针可以引用吗?或者说,
可以用指针指向另外一个指针吗?而且,被指向的指针为nil时,指向它的指针也
自动为nil?有这个可能性吗?
可能我的问题问的很外行,请大家不要笑话。
 
Beta:
谢谢了!收藏!
 
多谢小雨哥,您和温柔一刀的第二点说的是一个问题。
这的确是个限制,不过并不是不能解决,只是又要麻烦一点了:)
可以借用 COM 的方法,我的私有变量不用一个指针,而是一个 TList:
type
TTest = class(TComponent)
private
FPtrList: TList;
public
class procedure CreateObj(var Obj: TTest;
AOwner: TComponent);
destructor Destroy;
override;
procedure GetRef(var NewRef: TTest);
procedure DelRef(TheRef: TTest);
end;

class procedure TTest.CreateObj(var Obj: TTest;
AOwner: TComponent);
begin
Obj := Create(AOwner);
// 调用构造函数生成实例
Obj.FPtrList := TList.Create;
Obj.FPtrList.Add(@Obj);
// 将指向实例的指针保存到列表中
end;

destructor TTest.Destroy;
var
i: Integer;
begin
for i := 0 to FPtrList.Count - 1do
TObject(FPtrList^) := nil;
FPtrList.Free;
inherited;
end;

procedure TTest.GetRef(var NewRef: TTest);
begin
if FPtrList.IndexOf(@NewRef) < 0 then
begin
NewRef := TTest(FPtrList.First^);
// 到这里,列表中肯定至少有一个
FPtrList.Add(@NewRef);
end;
end;

procedure TTest.DelRef(TheRef: TTest);
begin
FPtrList.Remove(TheRef);
end;

测试代码:
var
Test, Test2: TTest;
procedure TForm1.Button1Click(Sender: TObject);
begin
if Assigned(Test) then
ShowMessage('Assigned')
else
ShowMessage('Not assigned');
TTest.CreateObj(Test, nil);
Test.GetRef(Test2);
if Assigned(Test2) then
ShowMessage('Assigned2')
else
ShowMessage('Not assigned2');
Test2.Free;
// 调用成功,说明至少实现了 Test2 := Test

if Assigned(Test) then
ShowMessage('Assigned')
else
ShowMessage('Not assigned');
if Assigned(Test2) then
// 测试成果 :-)
ShowMessage('Assigned2')
else
ShowMessage('Not assigned2');
// 答案是它,Hooray,成功了!
end;

像这样就可以解决多指针引用的问题:) 看起来好像比较麻烦,不过在特定的时候
这还是很有必要的:)
请大家继续指正,欢迎继续讨论。
 
C#好,自动清除不用的对象
 
//C#...自动清除不用的对象
呵呵,它后出,而且是一个妈生的,当然了:)
 
C#没有指针。
 
坚决收藏!好东东,呵呵。
 
几天没来,变化真大.
 
Beta 的代码只适用于把指针声明在静态区(全局变量)的情况,如果用在
栈区(局部变量)肯定要有麻烦.FPtrList里面的指针可能已经被释放了,Destroy
过程就会出错.
 
xeen: 多谢提醒,的确是这样的,不过我觉得对于栈指针似乎没有使用这以技术的必要:)
当然,使用的时候仍然应该注意这个问题。
zqw0117: 用一个指针指向另一个指针是可以并且容易的,不过,在释放被指的指针后,
要想同时清空源指针,似乎···很难:(
 
好人一生平安
 
今天头昏,作个记号,明天慢慢看!
 
to beta前辈:
受教!谢谢!继续听课。
 
beta 多出几篇,出本电子书吧
 
//beta 多出几篇
呵呵,不容易啊:
1.有空
2.有灵感
3.有心情:)
 
受益匪浅,收藏……
 
好东东!!
支持!
 
后退
顶部