关于Delphi类的实例化问题

先上代码自定义类:unitmyClass;interfacetypeTmyClass=class(TObject)private{privatedeclarations}... 先上代码
自定义类:
unit myClass;
interface
type
TmyClass = class(TObject)
private
{ private declarations }
protected
{ protected declarations }
public
function Rstr(s: string):string;
class function staticDemo(s: string):string;
{ public declarations }

published
{ published declarations }
end;
//var
//tm: TmyClass;

implementation
function TmyClass.Rstr(s: string):string;
begin
Result := 'TmyClass.Rstr := ' + s;
end;
class function TmyClass.staticDemo(s: string):string;
begin
Result := 'static function ' + s;
end;
end.

问题:
procedure TForm2.FormShow(Sender: TObject);
var
s: string;
tm: TmyClass;
begin

//ShowMessage(TmyClass.Rstatic('haha...static'));
ShowMessage(tm.Rstr('a'));
为什么我只是声明了一个tm没有实例化(Create) Rstr为什么可以调用成功,它又不是一个静态的
难道说在声明的同时Delphi自己就把这个类给实例化过了?
展开
 我来答
高永存的编程小站
2012-10-06 · TA获得超过181个赞
知道小有建树答主
回答量:163
采纳率:0%
帮助的人:117万
展开全部
我想,静态方法与动态方法的区别就是,静态方法是需要在不创建对象的情况下使用,所以,为了使用静态方法,编译程序就需要在应用程序加载到内存后就把类的代码和静态变量加载到内存中,这时就可以使用静态变量和方法了。不管你创建了多少实例,每个实例的方法的代码(包括静态和动态的),在内存中应该只存在一份(就是应用程序加载时的那份),静态变量应该也只有一份,而动态变量却要创建在实例中,有几个实例就有几份。所以说,不管静态方法还是动态方法,应该是都可以调用了,只不过,动态方法有可能要使用实例里边的动态变量,不创建实例就没有实际分配变量空间,如果编译器不检查,动态方法应该也是能调用的,只不过可能会出现非法内存操作错误。
所以我猜,只要在动态方法里不使用动态变量,并且编译器不做限制,动态方法应该是完全可以调用的,而且不会出错。(其实,动态方法如果不使用动态变量,它实现的就是静态方法的功能。)
追问
是的,如果在不实现一个类的情况下不能访问类的私有变量,通过方法去访问私有变量会报内存错误,这么写感觉有点不规范。。谢了
追答
仔细看了看你的代码,你的代码实现上是钻了delphi编译器的空子,按说你应该有一行tm:=TmyClass.Create;的,你没写,delphi给出了警告,但没说是错误。因为代码只有一份,delphi不管你是否生成实例,都把方法的代码做了正确的定位。
不创建实例来使用私有变量是不行的,因为私有变量是动态的。如果你想不创建实例来使用静态变量是可以的。但delphi的类里好像不能定义公用的静态变量,这没关系,你可以在单元文件里定义静态变量来代替类里的静态变量。
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TestClass=class
public
class function GetCount:string;
end;
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
count:Integer=0;
implementation
{$R *.dfm}
class function TestClass.GetCount:string;
begin
Inc(count);
result:=IntToStr(count);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage(TestClass.GetCount);
end;
end.

忽略编译器的错误是个非常不好的习惯,会使你的大一点的程序很难调试。
pascal是个非常经典和比较完美的语言,它的语法严谨,所以一般情况下,只要编译后没有错误和警告,程序基本上就已经行了,这是其它比较宽松的语言(如有C/C++/JAVA/C#)等不能比的,我们应该利用这个优势来提高编程和调试的效率。只要代码有警告或错误,就一定要把它们解决了之后再执行。
光点科技
2023-08-15 广告
通常情况下,我们会按照结构模型把系统产生的数据分为三种类型:结构化数据、半结构化数据和非结构化数据。结构化数据,即行数据,是存储在数据库里,可以用二维表结构来逻辑表达实现的数据。最常见的就是数字数据和文本数据,它们可以某种标准格式存在于文件... 点击进入详情页
本回答由光点科技提供
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式