一个小问题....大侠们进来看看...解释一下 多谢(50分)

  • 主题发起人 主题发起人 令狐小侠
  • 开始时间 开始时间

令狐小侠

Unregistered / Unconfirmed
GUEST, unregistred user!
TA = class
public
function test:string;
end;
function TA.test: string;
begin
result := 'aa';
end;
{------------------------}
procedure TForm1.Button1Click(Sender: TObject);
var
A : Ta;
begin
A := Ta(Tobject.Create);//这个地方创建的时候,因该是为一个Tobject分配了内存
而不是为TA 分配的.
看书上说类型转化只是改变的,执行框架而已.
a.test;//这个地方我决定应该报地址错误的.可是执行很正常..请大侠解释下.

a.Free;
end;
 
有趣的问题,关注,这样的向下转型是会有问题,这样试试看
procedure TForm1.Button1Click(Sender: TObject);
var
A : Ta;
tmpObject: TObject;
begin
tmpObject := TObject.Create;
A := Ta(tmpObject);//这个地方创建的时候,因该是为一个Tobject分配了内存
而不是为TA 分配的.
看书上说类型转化只是改变的,执行框架而已.
a.test;//这个地方我决定应该报地址错误的.可是执行很正常..请大侠解释下.

a.Free;
end;
 
nicai_wgl :你那样还是很正常...
 
语句正常啊。当然不会报错。
A := Ta(Tobject.Create); //这里先创建了Tobject,地址转换成Ta类型保存到A。应该是在转换成TA时系统自动重新分配了空间。所以A.test不会出错。
 
类型转化的时候会重新分配内存吗????????书上说 类型转化 只是改变的 他的 执行 框架而已!!!!
 
关注这个问题:
ta = class(TObject)
public
function Test(): String;
function www(): Integer;
end;

tb = class(TObject)
public
function sum(): Integer;
end;

function ta.Test: String;
begin
Result := '11';
end;

function ta.www: Integer;
begin
Result := 1 + 4;
end;

{ tb }

function tb.sum: Integer;
begin
Result := 1 + 3;
end;

procedure TForm1.BitBtn1Click(Sender: TObject);
var
a: Ta;
b: tb;
s: Integer;
begin
b := tb.Create;
a := Ta(b);
S := a.www;
ShowMessage(IntToStr(S));
a.Free;
end;
我试了一下,这样都可以,我用的是Delphi6.0。
 
我晕....看来这个问题...要高手解释一下啊....
 
TA = class
private
public
procedure Test;
end;

TB = class
private
public
procedure Test;
end;
var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
A: TA;
B: TB;
begin
A := TA.Create;
B := TB(A);
B.Test;
B.Free;
end;

{ TA }

procedure TA.Test;
begin
ShowMessage('I am TA Class!');
end;

{ TB }

procedure TB.Test;
begin
ShowMessage('I am TB Class!');
end;

这样也是正常的,在TB(A)的时候,Test函数地址转换过了。
 
TA = class
private
FClassA: string;
public
constructor Create;
procedure TestA;
end;

TB = class
private
FClassB: string;
public
constructor Create;
procedure TestB;
end;
var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
A: TA;
B: TB;
begin
A := TA.Create;
B := TB(A);
A.TestA;
B.TestB;
B.Free;
end;

{ TA }

constructor TA.Create;
begin
FClassA := 'I am TA Class!';
end;

procedure TA.TestA;
begin
ShowMessage(FClassA);
end;

{ TB }

constructor TB.Create;
begin
FClassB := 'I am TB Class!';
end;

procedure TB.TestB;
begin
ShowMessage(FClassB);
end;

这样就不对了,所以在TB(A)的时候,只是对函数地址进行转换,内存是不做重新分配的。
 
运行是很正常,但作法是错的,内存访问错误会导致不可预知的错误,当然
也包括什么错误也不报告.......
 
var
A : Ta;
begin
A := Ta(Tobject.Create);//这个地方创建的时候,因该是为一个Tobject分配了内存
而不是为TA 分配的.
看书上说类型转化只是改变的,执行框架而已.
a.test;//这个地方我决定应该报地址错误的.可是执行很正常..请大侠解释下.

a.Free;
end;

你定义的对象指针就是一个TA类型的指针, 我想编译器在分配内存时是按TA这个类来进行分配的,也就是说,你所创建的类的VT就是TA的,当然包括了TA所有的成员在内,而不是TObject的.
这就是"父类子对象"的创建吧.事实上,编译器管理的东西还是按子类的大小了.呵~~
其实,编译器
 
这样作明显是错的,Object Pascal里类非virtual的成员方法在编译的时候就有
固定的地址,所以你能找到 TA.test方法入口,如果你把它定义成virtual试试,利马
出错。
另外即使不是virtual的方法,如果在方法里访问类的成员变量也会出错.

总之要记住:内存访问错误会导致不可预知的错误,当然
也包括什么错误也不报告
 
伤心的石头 为什么分配的是Ta的 而不是Tobject的啊?
 
晕倒,你先了解关于类中数据成员和成员函数的内存分配机制,就知道这个问题就不叫问题。
 
C++中很多基本书籍都会探讨这些问题,但是Delphi的书籍呢,很少会剖析这些的。所以我一向认为学程序设计最好先学C/C++。
 
试试这个再想想吧:
type
Ta = class
public
function test(): string;
end;

//------------------------

function Ta.test(): string;
begin
Result := '这是一个没有太多意义的成员函数,其内存分配与对象创建无关!';
end;

procedure TForm1.Button1Click(Sender: TObject);
var
a: Ta;
begin
a := nil;
ShowMessage(a.test());
end;
 
en,建议试完了,再把function test(): string;定义后加virtual或者dynamic,看
又是个什么结果.
 
来自:风林坡, 时间:2006-11-24 11:44:28, ID:3631095
C++中很多基本书籍都会探讨这些问题,但是Delphi的书籍呢,很少会剖析这些的。所以我一向认为学程序设计最好先学C/C++。
风 这个问题的说明是正确的,但你说Delphi的书籍很少会剖析这些的是错误的,李维就有一本这方面的书,说得非常详细,好像是 vcl 框架深入 ,具体名字忘了~~看盗版的没有仔细看书名~
 
to xiaohongna,
是的,Delphi剖析这方面的书有,但的确很少啊,真正深入的就更少了。
 
后退
顶部