delphi中对象create之后,默认存放的路劲是?

问题描述

delphi中对象create之后,默认存放的路劲是?

例如:Tinifile,Tbitmap,等等,不带路劲名,直接create('文件名.ini'),
怎么判断是否创建成功,是不是只有提前判断同名文件是否存在一种方法?

解决方案

在D中每个应用程序可以获得的内存空间分为两种:堆(heap)和栈(stack)。
堆又称为“自由存储区”,其中的内存空间的分配与释放是必须由程序员来控制的。例如,用GetMem函数获取了一定大小的内存空间,则在使用完后,必须调用FreeMem函数将空间释放,否则就会发生所谓的“内存泄漏”。“借债还钱,天经地义”。
栈又称为“自动存储区”,其中的内存空间的分配与释放是由编译器和系统自动完成的,不需要程序员过问。函数调用时按值传递的参数所占空间、函数中的局部变量等,都是在栈中被分配空间的。
Objecgt Pascal遵循所谓的“引用/值”模型。无论在参数传递还是变量定义中,简单类型(如Integer、Cardinal、char以及record等) 被按值传递或使用,其内存空间从栈中分配。而复杂类型(class)则被按引用传递或使用,其内存空间从堆中分配。在Object Pascal中,所有对象(类类型的)都被建立在内存的堆空间上,而非栈上。因此在创建对象时,其构造函数不会被编译器自动调用,也没有C++中所谓的 “默认构造函数”(默认构造函数:在C++中声明一个变量或一个类实例时候,自动调用相应的购造函数为该变量或实例分配内存控件,在D中的类类型对象都需 要程序员调用构造函数对其进行显式构造,分配内存)调用构造函数来创建对象以及调用析构函数来消灭对象都是程序员的职责。
定义构造函数使用Constructor关键字。按惯例,构造函数名称为Create(当然也可以用其他名称,但那绝非优良的设计)。如
Public
Constructor Create(strFatherName, strMotherName : String);
要创建出一个对象,首先需要分配对象本身所占用的内存空间,然后执行类的构造函数,以初始化各数据成员、申请对象需要的资源或创建其内部包含的子对象。构 造函数代码调用的是system.pas文件的第8949行的_ClassCreate函数(以Delphi 6为准),该函数具体为每个对象分配合适的内存。这个动作也就是所谓的“编译器魔法”(Compiler Magic),由这个动作完成真正的对象的内存分配,一个对象在这个时候已经有了外壳。
内存分配完成后是调用类的构造函数,即TMyClass.Create(),以初始化数据成员。构造函数由定义类的程序员编写,也就是说,将对象初始化成何种模样是由程序员决定的。至此,一个对象已经诞生了。
由于对象本身所占内存的分配是由编译器完成的,因此即使没有构造函数,对象也一样可以被构造。构造函数的职责只是初始化对象的数据成员,没有构造函数只意 味着不会对数据成员进行初始化而已,编译器会对所有数据进行清零初始化。此外,由于Object Pascal中所有类(除了TObject类本身)都是从TObject类派生,因此编译器会调用TObject.Create()构造函数。不过,这个 函数只是一个空函数(只负责为类分配内存空间,但不进行类中成员的初始化工作)。
注意:在方法或函数中声明一个类类型变量的时候。编译器给这个变 量一个4字节的地址空间在栈上。它并不代表任何东西,只是一个指针而已(所以类类型变量名称实质上都是指针而已,普通的赋值操作,赋予的也只是指针地址而 已,并没有给新变量另辟空间存储)。在函数或方法中,定义的类类型变量需要被初始化后才能使用,也就是被create后才能被正确访问。create后在 堆中分配相应的空间,而声明的变量则指向该段内存。但是当函数结束后如果该类类型变量不需要被传递到外界使用,那么应该及时的free掉,也就是进行析 构,否则将发生内存泄漏,即该内存空间一直都被该变量占用。如果要传递到外界,那么也就是result:=类类型变量A(result是编译器给函数的默 认的一个变量,未赋值前也是一个4字节地址控件而已,负责传递变量)。result:=类类型变量A后,result指向了类类型变量A,也就是说 result和A都指向同一个对象,修改result和A都是一样的结果。这种情况下,也就是类类型变量A需要被传递时候,在函数内不需要被free.但 是函数将A传递给主调函数中的类类型变量B后,也就是B:=A,B也指向A的内存空间,那么在B的使用期结束后就需要对B进行free,也就对A进行 free了,就不容易出现内存泄漏。
定义析构函数使用Destructor关键字。按惯例,析构函数名称为Destroy。与构造函数类似,如果在类中没有特殊的资源需要被释放,也可以不定 义析构函数,TObject同样定义了一个空的析构函数。在析构对象的时候,应该调用对象的Free()方法而不是直接调用Destroy()。这是因 为,在TObject的Free()方法中会判断对象本身是否为nil,如果不为nil则调用对象的Destroy(),以增加安全性。永远不要直接调用 对象的Destroy(),而应该是Free()。要销毁一个对象,其顺序与创建对象正好相反。首先是释放对象申请的资源以及销毁内部的子对象,之后是回 收对象本身所占的内存空间。
销毁一个全局对象变量的时候,通常将对象设置为nil,这样就不会留下一个含非法指针的变量。当析构函数或者一个由析构函数调用的方法引用了该变量的 时候,如果该变量成了nil,则可以避免任何潜在的问题。free方法也不会自动将对象置为nil,所以在调用free之后,最好是在手动将对象设置为 nil。可以使用sysutils单元中的方法freeandnil过程——freeandnil(obj)。

    构造函数和析构函数的目的在于一个类可以像普通类型那样初始化和销毁,从而保证了封装。在一个类的构造函数中分配的资源尽量要记得在析构函数中销毁。

    另外,在VCL类中,对象的销毁还应注意顺序,VCL的组织形式:属主(owner)机制。从TComponent开始,VCL类的构造函数就带有一个参 数AOwoner,它决定了这些类之间的树型关系。比如一个button放在form上,那么button的aowoner就是form。那么析构 form的时候,会先通知button析构。即析构的时候会通知自身拥有的对象先行析构,如此递归下去。这种属主机制是设计模式中典型的结构性模式 COMPOSITE(组合)。而递归析构的方式是典型的行为模式中的Observer(观察者模式),这是VCL中的消息处理的基本模式。

总 结:简单类型存放在栈中,由编译器管理其内存空间。声明时候就已经分配了内存空间。赋值后的两个变量属于不同的变量。但是类类型存放在堆中,需要程序员管 理,需要对其进行create和destroy,赋值以后被赋值的对象仍然指向赋值的变量内存空间,并没有创建属于自己的内存空间。

解决方案二:

默认放在程序的工作路径。所谓工作路径,如果你是在ide中启动,那么很可能和delphi主程序在一个路径。
如果是双击程序启动,那么和程序exe在一个路径。你也可以给程序创建一个快捷方式,并且在快捷方式的属性中设置工作路径。

解决方案三:

好像不对,例如:
procedure TForm1.Button1Click(Sender: TObject);
var INISVN:Tinifile;
begin
INISVN:=Tinifile.Create('BenDaS.ini'); // BenDaS.ini'
edit1.Text:=INISVN.ReadString('SYSDB','服务器名','SONG');
INISVN.WriteString('SYSDB','服务器名','SONG');
end;
创建的文件最后在C:Windows
这个路径是怎么配置的,可以指定生成到项目编译realse的路径下么?
其他类似的路径又是怎么设定的。
此外,对象Create之后,我们怎么知道对象是否被成功创建,
还是只能先判断是否存在,不存在创建,存在先删除或不创建?

解决方案四:

我一般用create(changefileext(applicationname, ini))

解决方案五:

http://www.cnblogs.com/lilongjiang/p/3969491.html

解决方案六:

TBitmap.SaveToFile('1/bmp')

时间: 2024-09-16 10:08:43

delphi中对象create之后,默认存放的路劲是?的相关文章

Delphi中对象解除技巧

在Delphi程序设计中,我们需要通过解除建立的所有对象来避免内存泄漏.但是,如果你在程序中不谨慎小心的话,很容易多次解除同一个对象,这将会引起很严重的错误,造成应用程序崩溃,甚至是死机. 请看下面的程序: procedure TForm1.Button1Click(Sender:TObject); var Button2,Button3:TButton; begin Button2:=TButton.Create(self); Button3:=TButton.Create(Button2);

Delphi中的TWebBrowser与MSHTML(5):document对象的属性、方法和事件

{IHTMLDocument2 方法:} write //写入 writeln //写入并换行 open //打开一个流,以收集 document.write 或 document.writeln 的输出 close //关闭并输出用 document.open 方法打开的流 clear //清空文档中所有元素, 可能暂时不支持 queryCommandSupported //是否支持指定命令 queryCommandEnabled //指定命令是否有效 queryCommandState //

Delphi中的线程类 - TThread详解<转>

Delphi中有一个线程类TThread是用来实现多线程编程的,这个绝大多数Delphi书藉都有说到,但基本上都是对TThread类的几个成员作一简单介绍,再说明一下Execute的实现和Synchronize的用法就完了.然而这并不是多线程编程的全部,我写此文的目的在于对此作一个补充.线程本质上是进程中一段并发运行的代码.一个进程至少有一个线程,即所谓的主线程.同时还可以有多个子线程.当一个进程中用到超过一个线程时,就是所谓的"多线程".那么这个所谓的"一段代码"

Delphi中的SQL编程

SQL语言作为关系数据库管理系统中的一种通用的结构查询语言,已经被众多的数据库管理系统所采用,如ORACLE.Sybase.Informix等数据库管理系统,它们都支持SQL 语言.Delphi与使用SQL语言的数据库管理系统兼容,在使用Delphi开发数据库应用程序时,我们可以使用SQL语言编程,支持SQL编程是Delphi的一个重要特征,这也是体现Delphi作为一个强大的数据库应用开发工具的一个重要标志. 17.1 SQL语言简介 17.1.1 SQL的历史 在70年代初,E.E.Codd

Delphi中保存图像列表

最近在做项目时遇到将图像列表(TImageList)中一系列的图像保存到指定的文件或二进制流中,以便在需要时进行动态恢复的情况. 于是在Delphi的帮助中查找TImageList类相关的属性.方法,遗憾的是Delphi在TImageList中并未提供SaveToFile和SaveToStream方法,所以针对TImageList目前的限制,必须采取其它的办法来扩展TImageList的功能,以满足实际项目的需要. 解决方法 方法一: 使用API函数ImageList_Write和ImageLi

怎样在DELPHI中实现文件切割/组合

一. 文件切割/组合原理 所谓文件切割,就是把一个文件切割成若干个小文件.做法就是将一个文件对象以"文件流"的方式读出,然后按照一定的块(Block)大小分别存成文件.文件组合,就是把若干个文件组合成一个文件.比如像打包工具(Wise)用到的就是这个原理.如果大家对"流"这个概念熟悉的话,那么实现起来就很容易了,以下就是实现步骤. 二. 实现 在DELPHI中新建一个工程,然后在窗体中加入两个BUTTON,一个EDIT,一个OPENDIALOG,一个SAVEDIAL

浅析Java中对象的创建与对象的数据类型转换_java

Java:对象创建和初始化过程 1.Java中的数据类型    Java中有3个数据类型:基本数据类型(在Java中,boolean.byte.short.int.long.char.float.double这八种是基本数据类型).引用类型和null类型.其中,引用类型包括类类型(含数组).接口类型.     下列语句声明了一些变量: int k ; A a; //a是A数据类型的对象变量名. B b1,b2,-,b10000;// 假定B是抽象类或接口. String s;      注意:从

Delphi中的消息处理

1.windows的消息驱动体系 在windows系统中,消息传递是实现对乡间通信和控制的主要手段.可以额系统都以消息驱动的方式工作.系统中发生的用户输入操作.显示信息的改变.系统环境参数变化等所有时间都以系统定义消息的形式出现在相关的应用程序和窗口.所以程序设计的主要任务就是为这些消息的处理设计代码. 在应用程序中,发送者可以通过发送消息要求接收者完成相应的处理.当程序运行时,windows系统为每个应用程序实例建立一个消息队列,一次保存发送给该程序实例的消息,在应用程序的主控部分,需要设置一

在Delphi中的Access技巧集

1.DELPHI中操作ACCESS数据库(建立.mdb文件,压缩数据库) 以下代码在WIN2K,D6,MDAC2.6下测试通过, 编译好的程序在WIN98第二版无ACCESS环境下运行成功. //在之前uses ComObj,ActiveX //声明连接字符串 Const SConnectionString = 'Provider=Microsoft.Jet.OLEDB.4.0;Data Source=%s;' +'Jet OLEDB:Database Password=%s;'; //====