W
wr960204
Unregistered / Unconfirmed
GUEST, unregistred user!
虽然Delphi2006正式版还没有上市.但网络上已经有流露出来的版本.下载试用了一下
Delphi8和Delphi2005 for .NET早就实现了操作符重载.
现在新的Delphi2006中Win32部分的记录也支持操作符重载了.
根据Delphi2006的帮助说记录已经可以支持方法和属性了.
为了有别于类,
1.记录不可以继承.没有继承protected成员就没有意义了.所以记录只有Private和Public两种封装方式.
2.记录可以是变体型记录.类不行.
3.记录是职类型,而类是引用类型(引用和指针的混合体)
4.记录可以操作符重载.而类只有在Delphi.NET中才能实现操作符重载
5.记录构造器必须有一个或多个参数.
6,记录没有析构器
7,因为没有继承所以记录也不能有虚方法/动态方法.
8.Delphi Win32记录不能绑定接口.当然Delphi.NET可以
记录支持上面的先进功能以后对以前的代码几乎没有影响.首先和类一样,记录的方法不占用实例的存储空间,记录不支持虚方法/动态方法,也就没有VMT/DMT所占的空间.所以记录在内存中的存储方式和以前版本的没有方法的记录完全一样.属性其实就是读和写的方法也是不占用实例存储空间的.
上面扩展的功能里面最让我激动的就是Win32部分地记录也支持操作符重载了.
那样的话我们可以建立自己的字符串类型记录,可以是现"+",":="等等的重载.也可以实现矩阵记录.很轻松就能实现矩阵的乘法等计算.(记得Danny的博客上说以后要让Delphi支持各种几何和数学函数库.估计让记录支持操作符重载就是打的伏笔)
于是我无聊之中实现了一个字符串扩展TStrEx来体验了一下Delphi2006的记录操作符重载.
怎一个爽字了得!!哈哈
使用方式如下:
var
K:TStrEx;
begin
K :=' ?';
K := K + '的长度是 %d'
//和字符串相加
K := K.Trim()
//去掉空格
K[1] := 'K';
K := K.Format([K.Length])
//格式化
ShowMessage(K)
//显示
end;
很爽吧.以前的Delphi程序员看了一定会叫起来.TStrEx到底是简单的字符串类型还是类啊.呵呵
TStrEx的实现代码如下.
{
Delphi2006操作符重载体验.爽!
By wr960204(王锐) 2005/12/12
}
unit StringExUtils;
interface
uses
SysUtils;
Type
{增强字符串}
TStrEx =record
private
FBuf:String;
procedure SetLength(const Value: Cardinal);
function GetLength: Cardinal;
function GetChar(Index: Integer): char;
procedure SetChar(Index: Integer
const Value: char);
public
{重载操作符}
class operator Implicit(Str: String): TStrEx;// 重载 :=
class operator Implicit(Str: TStrEx): String;// 重载 :=
class operator Add(Str1,Str2:TStrEx): TStrEx;// 重载 +
class operator Add(Str1:String;Str2:TStrEx): TStrEx;// 重载 +
class operator Add(Str1:TStrEx;Str2:String): TStrEx;// 重载 +
class operator Explicit(Str: TStrEx): Pointer
// 重载强制转换Pointer()
class operator Explicit(Str: TStrEx): PChar
// 重载强制转换PChar()
class operator Explicit(Str: TStrEx): String
// 重载强制转换String()
{公有方法}
Function ToUpperCase():TStrEx;overload
// 大写
Function ToUpperCase(StartIndex,ALen:Integer):TStrEx;overload
// 部分大写
Function ToLowerCase():TStrEx;overload
// 小写
Function ToLowerCase(StartIndex,ALen:Integer):TStrEx;overload
// 部分小写
Function MdiStr(StartIndex,ALen:Integer):TStrEx
//取子字符串
Function LeftStr(ALen:Integer):TStrEx
//左边子字符串
Function RightStr(ALen:Integer):TStrEx
//右边子字符串
Function Insert(Index:Integer
Str:TStrEx):TStrEx
//插入
Function Delete(StartIndex,ALen:Integer):TStrEx
//去掉
Function Append(Str:TStrEx):TStrEx;
Function Trim():TStrEx
//去掉两边空格
Function TrimLeft():TStrEx
//去掉左边空格
Function TrimRight():TStrEx
//去掉右边空格
Function Pos(SubStr:TStrEx):Integer
//定位
Function Replace(FromStr,ToStr:TStrEx):TStrEx;overload
//替换
Function Replace(FromStr,ToStr:TStrEx;Flags: TReplaceFlags):TStrEx;overload
//替换
Function Format(const Args: array of const):TStrEx
//格式化
Function Fill(C:Char):TStrEx
//填充字符
{属性}
property Chars[Index:Integer]:Char read GetChar write SetChar
default;
property Length:Cardinal read GetLength write SetLength;
end;
implementation
{ TStringEx }
class operator TStrEx.Add(Str1, Str2: TStrEx): TStrEx;
begin
Result.FBuf := Str1.FBuf + Str2.FBuf;
end;
class operator TStrEx.Add(Str1: String
Str2: TStrEx): TStrEx;
begin
Result.FBuf := Str1 + Str2.FBuf;
end;
class operator TStrEx.Add(Str1: TStrEx
Str2: String): TStrEx;
begin
Result.FBuf := Str1.FBuf + Str2;
end;
function TStrEx.Append(Str: TStrEx): TStrEx;
begin
Result.FBuf := Self.FBuf + Str.FBuf;
end;
function TStrEx.Delete(StartIndex, ALen: Integer): TStrEx;
var
I:Integer;
begin
Result.Length := Self.Length - ALen;
for I:= 1 to Self.Length do
begin
if I < StartIndex then
begin
Result.FBuf := Self.Fbuf;
end
else
if (I >=StartIndex + ALen) then
begin
Result.FBuf[I - ALen] := Self.Fbuf;
end;
end;
end;
class operator TStrEx.Explicit(Str: TStrEx): Pointer;
begin
Result := PChar(Str.Fbuf);
end;
class operator TStrEx.Explicit(Str: TStrEx): PChar;
begin
Result := PChar(Str.Fbuf);
end;
class operator TStrEx.Explicit(Str: TStrEx): String;
begin
Result := Str.FBuf;
end;
function TStrEx.Fill(C: Char): TStrEx;
begin
Result.Length := Self.Length;
if Result.Length = 0 then
Exit;
System.FillChar(Result.FBuf[1],Result.Length,C);
end;
function TStrEx.Format(const Args: array of const): TStrEx;
begin
Result.FBuf := SysUtils.Format(Self.FBuf,Args);
end;
function TStrEx.GetChar(Index: Integer): char;
begin
Result := FBuf[Index];
end;
function TStrEx.GetLength: Cardinal;
begin
Result := System.Length(FBuf)
end;
class operator TStrEx.Implicit(Str: String): TStrEx;
begin
Result.FBuf := Str;
end;
class operator TStrEx.Implicit(Str: TStrEx): String;
begin
Result := Str.FBuf;
end;
function TStrEx.Insert(Index: Integer
Str: TStrEx): TStrEx;
var
I:Integer;
begin
Result.Length := Self.Length + Str.Length;
for I := 1 to Result.Length do
begin
if I < Index then
begin
Result.FBuf := Self.FBuf;
end
else
if (I >=Index)and(I<Index + Str.Length) then
begin
Result.FBuf := Str.FBuf[I - Index+1];
end
else
if I>=Index + Str.Length then
begin
Result.FBuf := Self.FBuf[I - Str.Length];
end;
end;
end;
procedure TStrEx.SetChar(Index: Integer
const Value: char);
begin
FBuf[Index] := Value;
end;
procedure TStrEx.SetLength(const Value: Cardinal);
begin
System.SetLength(FBuf,Value);
end;
function TStrEx.LeftStr(ALen: Integer): TStrEx;
begin
Result := MdiStr(1,ALen);
end;
function TStrEx.Pos(SubStr: TStrEx): Integer;
begin
Result := System.Pos(SubStr.FBuf, Self.FBuf);
end;
function TStrEx.Replace(FromStr, ToStr: TStrEx): TStrEx;
begin
Result := Replace(FromStr, ToStr, [rfReplaceAll]);
end;
function TStrEx.Replace(FromStr, ToStr: TStrEx
Flags: TReplaceFlags): TStrEx;
begin
Result.FBuf := SysUtils.StringReplace(Self.FBuf,FromStr,ToStr,Flags);
end;
function TStrEx.RightStr(ALen: Integer): TStrEx;
begin
Result := MdiStr(Self.Length-ALen + 1,ALen);
end;
function TStrEx.MdiStr(StartIndex, ALen: Integer): TStrEx;
begin
Result := Copy(FBuf,StartIndex, ALen);
end;
function TStrEx.ToLowerCase: TStrEx;
begin
Result := ToLowerCase(1,Length);
end;
function TStrEx.ToLowerCase(StartIndex, ALen: Integer): TStrEx;
var
I:Integer;
begin
Result.FBuf := Self.FBuf;
for I := StartIndex to StartIndex + ALen do
begin
if I > Length then
Exit;
if Result.FBuf in ['A'..'Z'] then
begin
Result.FBuf := Char(Ord(Result.FBuf)+32);
end;
end;
end;
function TStrEx.ToUpperCase: TStrEx;
begin
Result := ToUpperCase(1, Length);
end;
function TStrEx.ToUpperCase(StartIndex, ALen: Integer): TStrEx;
var
I:Integer;
begin
Result.FBuf := Self.FBuf;
for I := StartIndex to StartIndex + ALen do
begin
if I > Length then
Exit;
if Result.FBuf in ['a'..'z'] then
begin
Result.FBuf := Char(Ord(Result.FBuf)-32);
end;
end;
end;
function TStrEx.Trim: TStrEx;
begin
Result.FBuf := SysUtils.Trim(Self.FBuf);
end;
function TStrEx.TrimLeft: TStrEx;
begin
Result.FBuf := SysUtils.TrimLeft(Self.FBuf);
end;
function TStrEx.TrimRight: TStrEx;
begin
Result.FBuf := SysUtils.TrimRight(Self.FBuf);
end;
end.
Delphi8和Delphi2005 for .NET早就实现了操作符重载.
现在新的Delphi2006中Win32部分的记录也支持操作符重载了.
根据Delphi2006的帮助说记录已经可以支持方法和属性了.
为了有别于类,
1.记录不可以继承.没有继承protected成员就没有意义了.所以记录只有Private和Public两种封装方式.
2.记录可以是变体型记录.类不行.
3.记录是职类型,而类是引用类型(引用和指针的混合体)
4.记录可以操作符重载.而类只有在Delphi.NET中才能实现操作符重载
5.记录构造器必须有一个或多个参数.
6,记录没有析构器
7,因为没有继承所以记录也不能有虚方法/动态方法.
8.Delphi Win32记录不能绑定接口.当然Delphi.NET可以
记录支持上面的先进功能以后对以前的代码几乎没有影响.首先和类一样,记录的方法不占用实例的存储空间,记录不支持虚方法/动态方法,也就没有VMT/DMT所占的空间.所以记录在内存中的存储方式和以前版本的没有方法的记录完全一样.属性其实就是读和写的方法也是不占用实例存储空间的.
上面扩展的功能里面最让我激动的就是Win32部分地记录也支持操作符重载了.
那样的话我们可以建立自己的字符串类型记录,可以是现"+",":="等等的重载.也可以实现矩阵记录.很轻松就能实现矩阵的乘法等计算.(记得Danny的博客上说以后要让Delphi支持各种几何和数学函数库.估计让记录支持操作符重载就是打的伏笔)
于是我无聊之中实现了一个字符串扩展TStrEx来体验了一下Delphi2006的记录操作符重载.
怎一个爽字了得!!哈哈
使用方式如下:
var
K:TStrEx;
begin
K :=' ?';
K := K + '的长度是 %d'
//和字符串相加
K := K.Trim()
//去掉空格
K[1] := 'K';
K := K.Format([K.Length])
//格式化
ShowMessage(K)
//显示
end;
很爽吧.以前的Delphi程序员看了一定会叫起来.TStrEx到底是简单的字符串类型还是类啊.呵呵
TStrEx的实现代码如下.
{
Delphi2006操作符重载体验.爽!
By wr960204(王锐) 2005/12/12
}
unit StringExUtils;
interface
uses
SysUtils;
Type
{增强字符串}
TStrEx =record
private
FBuf:String;
procedure SetLength(const Value: Cardinal);
function GetLength: Cardinal;
function GetChar(Index: Integer): char;
procedure SetChar(Index: Integer
const Value: char);
public
{重载操作符}
class operator Implicit(Str: String): TStrEx;// 重载 :=
class operator Implicit(Str: TStrEx): String;// 重载 :=
class operator Add(Str1,Str2:TStrEx): TStrEx;// 重载 +
class operator Add(Str1:String;Str2:TStrEx): TStrEx;// 重载 +
class operator Add(Str1:TStrEx;Str2:String): TStrEx;// 重载 +
class operator Explicit(Str: TStrEx): Pointer
// 重载强制转换Pointer()
class operator Explicit(Str: TStrEx): PChar
// 重载强制转换PChar()
class operator Explicit(Str: TStrEx): String
// 重载强制转换String()
{公有方法}
Function ToUpperCase():TStrEx;overload
// 大写
Function ToUpperCase(StartIndex,ALen:Integer):TStrEx;overload
// 部分大写
Function ToLowerCase():TStrEx;overload
// 小写
Function ToLowerCase(StartIndex,ALen:Integer):TStrEx;overload
// 部分小写
Function MdiStr(StartIndex,ALen:Integer):TStrEx
//取子字符串
Function LeftStr(ALen:Integer):TStrEx
//左边子字符串
Function RightStr(ALen:Integer):TStrEx
//右边子字符串
Function Insert(Index:Integer
Str:TStrEx):TStrEx
//插入
Function Delete(StartIndex,ALen:Integer):TStrEx
//去掉
Function Append(Str:TStrEx):TStrEx;
Function Trim():TStrEx
//去掉两边空格
Function TrimLeft():TStrEx
//去掉左边空格
Function TrimRight():TStrEx
//去掉右边空格
Function Pos(SubStr:TStrEx):Integer
//定位
Function Replace(FromStr,ToStr:TStrEx):TStrEx;overload
//替换
Function Replace(FromStr,ToStr:TStrEx;Flags: TReplaceFlags):TStrEx;overload
//替换
Function Format(const Args: array of const):TStrEx
//格式化
Function Fill(C:Char):TStrEx
//填充字符
{属性}
property Chars[Index:Integer]:Char read GetChar write SetChar
default;
property Length:Cardinal read GetLength write SetLength;
end;
implementation
{ TStringEx }
class operator TStrEx.Add(Str1, Str2: TStrEx): TStrEx;
begin
Result.FBuf := Str1.FBuf + Str2.FBuf;
end;
class operator TStrEx.Add(Str1: String
Str2: TStrEx): TStrEx;
begin
Result.FBuf := Str1 + Str2.FBuf;
end;
class operator TStrEx.Add(Str1: TStrEx
Str2: String): TStrEx;
begin
Result.FBuf := Str1.FBuf + Str2;
end;
function TStrEx.Append(Str: TStrEx): TStrEx;
begin
Result.FBuf := Self.FBuf + Str.FBuf;
end;
function TStrEx.Delete(StartIndex, ALen: Integer): TStrEx;
var
I:Integer;
begin
Result.Length := Self.Length - ALen;
for I:= 1 to Self.Length do
begin
if I < StartIndex then
begin
Result.FBuf := Self.Fbuf;
end
else
if (I >=StartIndex + ALen) then
begin
Result.FBuf[I - ALen] := Self.Fbuf;
end;
end;
end;
class operator TStrEx.Explicit(Str: TStrEx): Pointer;
begin
Result := PChar(Str.Fbuf);
end;
class operator TStrEx.Explicit(Str: TStrEx): PChar;
begin
Result := PChar(Str.Fbuf);
end;
class operator TStrEx.Explicit(Str: TStrEx): String;
begin
Result := Str.FBuf;
end;
function TStrEx.Fill(C: Char): TStrEx;
begin
Result.Length := Self.Length;
if Result.Length = 0 then
Exit;
System.FillChar(Result.FBuf[1],Result.Length,C);
end;
function TStrEx.Format(const Args: array of const): TStrEx;
begin
Result.FBuf := SysUtils.Format(Self.FBuf,Args);
end;
function TStrEx.GetChar(Index: Integer): char;
begin
Result := FBuf[Index];
end;
function TStrEx.GetLength: Cardinal;
begin
Result := System.Length(FBuf)
end;
class operator TStrEx.Implicit(Str: String): TStrEx;
begin
Result.FBuf := Str;
end;
class operator TStrEx.Implicit(Str: TStrEx): String;
begin
Result := Str.FBuf;
end;
function TStrEx.Insert(Index: Integer
Str: TStrEx): TStrEx;
var
I:Integer;
begin
Result.Length := Self.Length + Str.Length;
for I := 1 to Result.Length do
begin
if I < Index then
begin
Result.FBuf := Self.FBuf;
end
else
if (I >=Index)and(I<Index + Str.Length) then
begin
Result.FBuf := Str.FBuf[I - Index+1];
end
else
if I>=Index + Str.Length then
begin
Result.FBuf := Self.FBuf[I - Str.Length];
end;
end;
end;
procedure TStrEx.SetChar(Index: Integer
const Value: char);
begin
FBuf[Index] := Value;
end;
procedure TStrEx.SetLength(const Value: Cardinal);
begin
System.SetLength(FBuf,Value);
end;
function TStrEx.LeftStr(ALen: Integer): TStrEx;
begin
Result := MdiStr(1,ALen);
end;
function TStrEx.Pos(SubStr: TStrEx): Integer;
begin
Result := System.Pos(SubStr.FBuf, Self.FBuf);
end;
function TStrEx.Replace(FromStr, ToStr: TStrEx): TStrEx;
begin
Result := Replace(FromStr, ToStr, [rfReplaceAll]);
end;
function TStrEx.Replace(FromStr, ToStr: TStrEx
Flags: TReplaceFlags): TStrEx;
begin
Result.FBuf := SysUtils.StringReplace(Self.FBuf,FromStr,ToStr,Flags);
end;
function TStrEx.RightStr(ALen: Integer): TStrEx;
begin
Result := MdiStr(Self.Length-ALen + 1,ALen);
end;
function TStrEx.MdiStr(StartIndex, ALen: Integer): TStrEx;
begin
Result := Copy(FBuf,StartIndex, ALen);
end;
function TStrEx.ToLowerCase: TStrEx;
begin
Result := ToLowerCase(1,Length);
end;
function TStrEx.ToLowerCase(StartIndex, ALen: Integer): TStrEx;
var
I:Integer;
begin
Result.FBuf := Self.FBuf;
for I := StartIndex to StartIndex + ALen do
begin
if I > Length then
Exit;
if Result.FBuf in ['A'..'Z'] then
begin
Result.FBuf := Char(Ord(Result.FBuf)+32);
end;
end;
end;
function TStrEx.ToUpperCase: TStrEx;
begin
Result := ToUpperCase(1, Length);
end;
function TStrEx.ToUpperCase(StartIndex, ALen: Integer): TStrEx;
var
I:Integer;
begin
Result.FBuf := Self.FBuf;
for I := StartIndex to StartIndex + ALen do
begin
if I > Length then
Exit;
if Result.FBuf in ['a'..'z'] then
begin
Result.FBuf := Char(Ord(Result.FBuf)-32);
end;
end;
end;
function TStrEx.Trim: TStrEx;
begin
Result.FBuf := SysUtils.Trim(Self.FBuf);
end;
function TStrEx.TrimLeft: TStrEx;
begin
Result.FBuf := SysUtils.TrimLeft(Self.FBuf);
end;
function TStrEx.TrimRight: TStrEx;
begin
Result.FBuf := SysUtils.TrimRight(Self.FBuf);
end;
end.