TForm1 = class(TForm)
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; Override;
end;var
frmA: TForm1;
begin
frmA := TForm1.create(nil); //怎样在创建完成后,在类内部的代码中,把frmA置为nil
end;
不知道构造函数create没有返回值,不知道怎么把实例的地址给变量的,我想要达到这样的目的:重载create或者什么方法,在create实例化对象完成后,把本应该赋值的变量给置为nil,如上例中,frmA := TForm1.create(nil); 后,frmA仍然是nil,这个可以做到吗?我想可能能做,因为create返回一个实例,应该有方法可以找到这个实例的首地址是给哪个变量的,如果找到这个方法,就可以这么做了,可惜我不会,求助一下,谢了
TForm1.create(nil); //怎样在创建完成后,在类内部的代码中,把frmA置为nil
或
frmA := TForm1.create(nil); //怎样在创建完成后,在类内部的代码中,把frmA置为nil
frmA := nil;
使用freeandnil(frmA)来释放。你是希望创建失败时,能返回nil,避免frmA被后续使用?
TForm.Create方法的参数指的是返回对象的拥有者,传递nil只不过是表示该对象没有拥有者而已。
忘了构造函数是否能返回nil的
不过你可以这样:
type
Pform=^Tform1;
procedure newobj(f:Pform);
begin
f^ := TForm1.create(nil);
if 失败 then
f^:=nil;
end;
begin
Self := nil;
if Self = nil then
ShowMessage('nil nil');
end;
2、要确保释放的实例变量都是nil,把XXX.Free方法改成FreeAndNil(XXX)
TMyObj = class
public
class function CreateObj(IsFree: Boolean): TMyObj;
end;{ TMyObj }class function TMyObj.CreateObj(IsFree: Boolean): TMyObj;
begin
Result := TMyObj.Create;
if IsFree then
FreeAndNil(Result);
end;procedure TForm1.Button1Click(Sender: TObject);
var
Obj: TMyObj;
begin
Obj := TMyObj.CreateObj(True);
if Obj = nil then
ShowMessage('nil');
end;
简单做法,取Application全局对象的地址,按字节往下搜,将搜到的地址看成PPointer,将其内容与Self指向的地址比较,如果相等则将搜到的地址中的内容置空。
试验过,可行,不过没这个必要,而且如果有那么巧合可能会搜索错误。
重载构造函数,在函数末尾加入
asm
xor eax,eax
end;
试试,通常Windows下都是用eax返回值的。给他清零,或者搞清楚nil的二进制表示,直接mov进去。
constructor TObj.Create;
begin
Self := nil;
end;
function CreateObj(AOwner: TComponent): TObj;
begin
try
Result := TObj.Create(AOwner);
except
Result := nil;
end;
end;
将原来的Create隐藏到 private
然后在public域定义一个类方法,名字叫Create并返回一个TObject(也就是模拟构造方法)
在这个函数内部调用隐藏的构造函数Create,然后返回一个nil
我在11楼的办法,应该还是有一定的的可行性的,就是用类的静态方法代替构造函数,这样,就可以在某种条件下返回nil,C++中经常采用这种形式,如C++版的Gdiplus中,Bitmap、Graphic类就是采用的这种办法代替构造函数。
一孔之见,仅供参考。
c := TCCC.Create(self);
c := nil;为什么我认为这个也许是可以实现的呢?因为create并没有定义Result,说明创建的self实例也许是在其它地方赋值给c的,这样,也许我就可以修改这个值,让它指向我希望它指向的地址。Seamour,我水平低,的确不知道NewInstance的用途,我一开始是用过NewInstance,但是,NewInstance似乎只在TObject实现,而我实际使用中,单例模式的类是从TForm继承的,用了NewInstance来实现单例,的确是可以,但是,创建的实例,完全没有TForm的特性,不能show,也不能接受sendmessage发过来的消息,就放弃了。看了26楼的连接,我又有了点想法,但是我不了解NewInstance,前面回复的都是高手,谁愿意指导我一下,解释下NewInstance?26楼的文中,有以下代码:
class function TSingleton.NewInstance: TObject;
begin
if ( not Assigned( Instance ) ) then
begin
Instance := inherited NewInstance;
// Initialize private variables here, like this:
// TSingleton(Result).Variable := Value;
end;
Result := Instance
Inc( Ref_Count );
end;
Result := Instance是什么意思呢?难道create返回的实例,就是NewInstance的Result?我试了下好像又不是,在我的例子里,总是报错。我实现单例模式的方法和别人的不太一样,如果能实现,应该是比较好的方式,我还想多了解些,看看能不能实现,无论能否实现,之后都会帖出代码。谢谢各位了。
type
TMyObj = class(TObject)
public
constructor Create;
end;{ TMyObj }constructor TMyObj.Create;
asm
mov ebx, esi
test dl, dl
jz @@exit
mov ebx, esi
mov eax, ebx
mov edx, [eax]
call dword ptr [edx - $1c]
pop dword ptr fs:[$00000000]
add esp, $0c
mov esi, 0
mov ebx,0
@@exit:
end;procedure TForm1.Button1Click(Sender: TObject);
var
a: TMyObj;
begin
a := nil;
a := TMyObj.Create;
if a <> nil then
a.Free
else
ShowMessage('空');
end;上面这段代码,每次调用都会返回一个nil,但是对象还是被创建了,也就是说,你每次创建,都将在内存中产生一个谁也找不到的对象。
这有什么意义呢?纯粹是在浪费内存
比如你定义了个变量SObj,那么,你可以 mov esi, [SObj],则返回的就是你定义的那个SObj
type
TMyObj = class(TObject)
private
FID: Integer;
public
constructor Create;
end;{ TMyObj }constructor TMyObj.Create;
{$J+}
const
SObj: TMyObj = nil;
{$J-}
begin
if SObj = nil then
begin
SObj := Self;
FID := 1;
end
else
begin
FID := 2;
asm
mov ebx, esi
test dl, dl
jz @@exit
mov ebx, esi
mov eax, ebx
mov edx, [eax]
call dword ptr [edx - $1c]
mov dl, $01
mov ecx,[eax]
call dword ptr [ecx-$04]
pop dword ptr fs:[$00000000]
add esp, $0c
mov esi, [SObj]
mov ebx,0
@@exit:
end;
end;
end;procedure TForm1.Button1Click(Sender: TObject);
var
a: TMyObj;
begin
a := TMyObj.Create;
ShowMessage('单例-对象地址:' + IntToHex(Integer(a), 8));
end;
自己Create的对象,要自己释放,然后再设为nil,比如:tempList := TStringList.Create();
tempList.Free();
tempList := nil;