如何用访问如下方法创建的对象中的域?(50分)

  • 主题发起人 主题发起人 liangliang
  • 开始时间 开始时间
L

liangliang

Unregistered / Unconfirmed
GUEST, unregistred user!
如何用访问如下方法创建的对象中的域?(或者说如何取得该对象的指针?)
with tclassname.createdo
begin
...;
end;
 
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
type
t=class(tobject)
procedure show;
end;

TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
implementation
{$R *.DFM}
procedure t.show;
begin
showmessage('shen');
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
with t.createdo
begin
show;
end;

end;

end.
 
对不起,连我自己都没看懂我要问什么。应该是:
如何访问用如下方法创建的对象中的域?(或者说如何取得该对象的指针?)
with tclassname.createdo
begin
...;
end;

To 沈前卫:
我不是这个意思。
我是说,我已经用with ..do
的行式动态地构造了一个对象(但没有取得该对象的指针),那么在别的地方(当然是不在with ..do
之内)我如何能访问该对象的域?
 
一定在这里要偷一行的懒(myclass := tmyclass.create)吗?
如果是的话, 那么以后你得用至少10行才能找到这个object啦.
如果你有兴趣的话研究一下TypInfo.pas吧, 也许你就知道怎么找
这个不知名的object了. (我看了1整天, 除了头昏之外没搞懂任何东西).
 
如果你的tclassname不是从TComponent继承下来的话,我想你已经丢失对此对象
的控制权,就象你盛情了内存,但没有指针指向它,又想通过指针访问它一样。
如果是从TComponent继承,可以使用以下代码访问:
var
I: Integer;
T,Temp: tclassname;
begin
T:=nil;
for I := ComponentCount - 1do
wnto 0do
begin
Temp := Components;
if (Temp is tclassname) and (Temp as tclassname).Name='YouClassName') then
begin
T:=(Temp as tclassName);
break;
end;
end;
if T<>nil then
......
end;
 
sorry,上面的代码应该将and (Temp as tclassname).Name='YouClassName')
去掉,因为你的Object是匿名的。
 
并非偷懒,而是动态创建的需要。
如果真的不行,那可不可以在with ..do
中把指针传给某变量。(好象在哪看到过)。
另外:我已在下面'如果有人参与讨论这个问题,请用EMail通知我。'打过勾了
为什么从没收到过mail?
 
如果这样,你的程序不能得到其指针,并且运行程序将造成内存泄漏!!!
不过可能是本人学识不够,不能继续帮助你。 但愿不是!!! {B-)
 
1、
tclassname p=tclassname.create;
with pdo
begin

...;//p就是指针
end;
不是很好?才多一行。
2、要是一定要用 with tclassname.createdo
那你的类 tclassname 里面多一个域,假设 PointeToSelf 吧
在你的类 tclassname 的constructor create里面加一行 PointeToSelf:=self
with tclassname.createdo
begin

//PointToSelf就是指向自己的针
end;
 
to PiPi.:
你的第一个方法是否就是myobject:=tmyclass.create?这样指针自然拿到了,可我要求
的是用with ..do
动态地创建对象(如:if .. then
with tmyclass.createdo
..),如果用
myobject:=tmyclass.create的方法,我要定义多少个myobject变量啊?当然,可以先静态的定
义一批变量数组,用时在调用,但终究觉得不是动态创建。
你的第二个方法,似乎是一个逻辑陷阱。我要取到myclass的指针就先要取到PointToSelf
的指针,可PointToSelf又是tmyclass中的域,所以要取到PointToSelf的指针,就得取到
myclass的指针。这不是个圈吗?
 
To liangLiang:
我向Pipi得意识是在tmyclass中加入一变量如PointToSelf,在Create函数中
PointToSelf:=Self;这样你在With快中可以访问PointToSelf,但你此时访问得
Self并不是你得tmyclass.create建立得对象,因为with只是在编译前起作用,对
编译后得代码没有影响! {B-)
 
只要定义一个^Tclassname类型的指针在with...do内把新建的类
的self指针赋给它就行了。否则会形成一个丢失的内存块。
 
To PiPi and 沈前卫:
如果PiPi的第二个方法是沈前卫所说的那样,那岂非多此一举了吗。因为在with块中我是
可以访问myclass域的,我还要pointtoself作什么。而一旦出了with块,我便失去了myclass
的控制权(myclass的指针),pointtoself自然也无从得到。
To firemeteor:
你的方法中的self应该并非是Tclassname对象的指针,大多数情况它将是form1的指针。
我想到了一个办法(不过可能有些烦):
大致思路是这样的:
即先定义一个tlist的父类(tfather),然后在定义须动态创建的子类(tchild)。创建时用
tlist的add方法将tchild的对象加上去。这样就可以用tfather.items得到动态对象的指针
了。而且还可以用count返回创建的数量,及调用tlist的方法管理所建对象。
代码大致如下:
tfather = class(tlist)
public
destructor Destroy;override;
...
end;
tchild = class //须动态创建的类
public
test:integer;
constructor create(Aparent:tobject);override;
...
end;
...
var
father:tfather;
implementation
destructor tfather.destroy;
var
i:integer;
begin
for i:=0 to count-1do
tchild(item).free;
inherited;
end;

constructor tchild.create(Aparent:tobject);
begin
inherited;
if Aparent is tlist then
begin

if Aparent = nil then
begin
Aparent := tlist.create;
end;
Aparent.add(self);
end;
end;

//用时可这样:
father:=tfather.create;
...
if .. then

with tchild.create(father)do
//
begin
..
end;
...
if father.count<>0 then
for i:=0 to father.count-1do
tchild(father.items).test:=0;
....
不知该法是否可行,还望各位指教。
 
不还是保存到变量吗?
不同之处只不过是保存到单个变量还是数组还是TList还是自定义的TList(是否多此一举?)中
而已
 
首先指出
if Aparent is tlist then
begin

if Aparent = nil then
begin
Aparent := tlist.create;
end;
Aparent.add(self);
end
应为:
if Aparent = nil then
Aparent := tlist.create;
else
if Aparent is tlist then
Aparent.add(self);

我们的原意是
PointToSelf在With块中访问,并将其保存到全局变量,因为在With中你可以
访问对象的域,但你得不到对象得地址,原因我已经说得很明白了:
<font color=red><b>因为with只是在编译前起作用,对编译后得代码没有影响!</b></a>
 
To Another_eYes:
我不否认该作法的实质仍然是将对象指针赋给某变量,事实上要通过指针访问对象的
域,该指针必然存在,且必须存在于某变量中。(否则,不靠指针(with块外)如何能访问?)
之所以不用单个变量是动态创建的限制,因为我无法确定要定义多少变量,况且动态创建
时也将非常困难,因为我将不得不先判断哪个变量已用过,哪个没有。有时甚至根本无法判断。
用数组也将同样面临这样的问题(如:应设多大上限,及创建的灵活性.)
之所以想到tlist是因为它能避开以上麻烦(只需简单的用一句tlist.add(..)即可),况且
它有众多方法和属性可用于管理所建对象。
之所以最终用tfather继承tlist的作法是因为须重载Destroy方法以释放所建的动态对象,另外
,可能还想自己添加一些域以扩展功能。
To 沈前卫:
我没看懂你为何要改成if .. then
.. else
的形式。这样一来你将可能丢失一个对象的指针,
而且可能引起混乱。举例说,如果你用tchild.create(father)动态创建时,father尚未创建,
那么此时传入的Aparent将是nil,执行Aparent := tlist.create;
后,将立即退出。不会再执行Aparent.add(self),因为你用的是if .. then
..else
句形,那么该对象的指针不是丢失了吗?
 
这样好了,看下面的代码:
var
p:TMemo;
begin
with TMemo.Create(Application)do
begin
asm mov p,eax //这时eax就是刚create的对象,一定要在with后面第一行,其他行就不一定是了。
end;
//其他代码
end;
ShowMessage(p.ClassName);
end;
 
这样好了,看下面的代码:
var
p:TMemo;
begin
with TMemo.Create(Application)do
begin
asm mov p,eax //这时eax就是刚create的对象,一定要在with后面第一行,其他行就不一定是了。
end;
//其他代码
end;
ShowMessage(p.ClassName);
p.Free();
//释放
end;

 
To 沈前卫:
Sorry ,我想我有点明白你的意思了。不过你可能也有一些失误。
应该是:
constructor tchild.create(Aparent:tfather);
begin
inherited;
if Aparent = nil then
Aparent := tfather.create;
Aparent.add(self);//if Aparent is tlist我觉得多余了。
end;
你是这个意思吗?
只是还不明白你为何要用if.. then
..else
.
 
To PiPi:
你这样不是变相的p := tmemo.create(application);吗?还烦了点。
还是那句话我要定义多少p变量,如何灵活地多次动态创建?
 
后退
顶部