zoukankan      html  css  js  c++  java
  • Delphi类型强制转换原理--没说清

    -------开发环境Delphi7----此篇仅供参考---

    -----------------

    这篇适用于Delphi7 ,因为Xe版的就不一样,好坑啊,具体原因暂时不清楚,以后弄明白了再写上来

    --------------------

    Unit

      1 unit Unit1;
      2 
      3 interface
      4 
      5 uses
      6   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      7   Dialogs, StdCtrls;
      8 
      9 type
     10   TmyClass=class
     11   private
     12     FName:string;
     13     FAge:Word;
     14   end;
     15 
     16    TmyClass_A=class(TmyClass)
     17    private
     18      FColor:String;
     19    property
     20      Color:string read FColor write FColor;
     21   end;
     22   TMyClass_X=class
     23     A:string;
     24     B:string;
     25     C:string;
     26   end;
     27 
     28   TForm1 = class(TForm)
     29     Button1: TButton;
     30     Memo1: TMemo;
     31     Button2: TButton;
     32     procedure Button1Click(Sender: TObject);
     33     procedure Button2Click(Sender: TObject);
     34   private
     35     { Private declarations }
     36   public
     37     { Public declarations }
     38   end;
     39 
     40 var
     41   Form1: TForm1;
     42 
     43 implementation
     44 
     45 {$R *.dfm}
     46 {以下例子说明:只想用浅显的东西理解强制转换这玩意 ,到底符不符合科学,俺就不管了}
     47 
     48 procedure TForm1.Button1Click(Sender: TObject);
     49 var
     50   vByte:Byte; //占用一个字节
     51   vChar:Char;//占用一个字节
     52   vInt:Integer;//占用四个字节
     53   vDou:Double;//占用8个字节
     54 begin
     55   memo1.Clear;
     56   //////先给vByte赋值,然后强制转换
     57   vByte:=65;//只能保存0..255之间的数字
     58   memo1.Lines.Add(Char(vByte)); //显示的是A  //表象:把vByte的内容强制转化为了Char类型,这个vByte的值真的改变了吗?不,没有改变,看下面
     59   memo1.Lines.Add(IntToStr(vByte));//vByte还是65
     60   //好像有点明白了,所谓的强制转换只不过是以某种类型去访问而已,用Char类型去访问Byte类型,没有真实的把把vByte的内容改变的
     61   vInt:=Integer(vByte);//vInt:=vByte 这样也可以的
     62   memo1.Lines.Add(IntToStr(vInt));
     63   vDou:=vByte;// Double(vByte)这个不能这样转换 ,浮点类型的转换比较特殊,为此还是用vDou:=vByte,这个编译器会实现转换的
     64 
     65   memo1.Lines.Add('----------------');
     66   //////////
     67   vInt:=1124;//这个超过了一个字节
     68   vChar:=Char(vInt); //用char类型去访问integer,把访问到的数据保存到vchar变量当中
     69   memo1.Lines.Add(vChar);//显示小写的b,因为char只能只能访问一个字节的内容这个1124超过了一个字节,vChar=Char(1124-1024),就是一个小写的b
     70   //看这个vByte就知道了上面vChar为啥是b了
     71   vByte:=vInt;//
     72   memo1.Lines.Add(IntToStr(vByte)); //显示100
     73 
     74   memo1.Lines.Add('----------------');
     75   /////////浮点类型很特殊,浮点类型有阶码之类的东西,不太熟,就不卖弄了
     76   vDou:=4095.3203125; //十进制的4095.3203125等于16进制的FFF.52
     77   //vByte:=vDou;//Double不能这么转化
     78   //vChar:=Char(vDou) 这个也不允许
     79   //不用试了,常规的要把浮点类型转化为整数、byte类型是不行的
     80   vInt:=Trunc(vDou); //这样了,把整数部分拿出来了
     81   Memo1.Lines.Add(IntToStr(vInt));
     82 
     83   ////好像没有说明白...........
     84   { 上面说到过这个
     85   vInt:=1124;//这个超过了一个字节
     86   vChar:=Char(vInt);
     87   用Char类型去访问Integer类型,那它只能容纳它那一字节的东西,也就是说它只能访问到一个字节的空间 1124的二进制是10001100100
     88   Char只能访问这个10001100100的后8位也就是01100100 ,这个01100100也就是十进制的100了
     89 
     90   Char读取Integer把范围变小了,但是Integer访问byte时,范围变大了,但是Byte最大也是255,这个integer访问Byte的变量,读到的也不会超过255
     91   }
     92 end;
     93 
     94 procedure TForm1.Button2Click(Sender: TObject);
     95 var
     96   vMyClass:TmyClass;
     97   vMyClass_X:TMyClass_X;
     98   Bool:Boolean;
     99 begin
    100   try
    101     vMyClass_X:=TMyClass_X.Create;
    102     vMyClass:=TmyClass.Create;
    103     vMyClass.FName:='Name_00';
    104     TmyClass_A(vMyClass).Color:='';
    105     ShowMessage(TmyClass_A(vMyClass).Color); //这里要报错的,强制转换,对啊,是强制转换,
    106     //强制转化的本质不是真的把某个类型的实例转换为另一个类型的实例,只是以某个类型的作用范围去访问另一个类型的实例而已
    107     //用这个TmyClass_A类型去访问TmyClass类型的实例vMyClass,TmyClass类没有FColor,vMyClass也不会有FColor,
    108     //用这个TmyClass_A的作用范围访问 TmyClass类型的实例vMyClass,vMyClass没有FColor,这样访问是会报错的
    109     //就算编译成功,还是会报错的
    110     //编译成功不意味着没有错误
    111     //这里报错的原因是vMyClass只有两个Field,而这个TmyClass_A有三个Field,TmyClass_A的字段分别是:FName,FAge,FColor
    112     //以这个TmyClass_A类型去访问了vMyClass对象的FColor,FColor在TmyClass中不存在,意味着TmyClass_A(vMyClass).FColor访问到的是一个不安全的地址
    113     //访问到不安全的地址很有可能会报错(Delphi7直接报错,DelphiXE释放vMyClass报错,DelphiXE6不报任何异常),
    114     //可能不报错的原因:可能是这些Delphi不同版本对 对象内的内存不安全访问的处理机制不一样;还有就是下面代码中的一种情况:情况1
    115 
    116     ShowMessage(TmyClass_A(vMyClass).FName); //这里就是对的 //因为都有FName
    117     //情况1  开始
    118     TmyClass_A(vMyClass_X).Color:='紫色'; //本人猜测这么赋值其实刚好赋值给了vMyClass_X的第三个Field也就是赋值给了vMyClass_X.C;
    119     ShowMessage(vMyClass_X.C);//紫色,充分证明猜想正确,TmyClass_A的实例中FColor排在第三个, vMyClass_X对象C也是排在第三个
    120     //充分证明了所谓的类型转换,其实没有真的把类型转掉,只不过是以某种类型的作用范围去访问另一个类型的实例而已
    121     ShowMessage(TmyClass_A(vMyClass_X).Color);
    122     //情况1  结束
    123   finally
    124     try
    125       FreeAndNil(vMyClass);
    126     except
    127       Bool:=True;
    128       FreeAndNil(vMyClass_X);
    129     end;
    130     if not Bool then
    131       FreeAndNil(vMyClass_X);
    132   end;
    133 end;
    134 end.

    Form

    object Form1: TForm1
    Left = 919
    Top = 353
    BorderStyle = bsDialog
    Caption = 'Form1'
    ClientHeight = 368
    ClientWidth = 199
    Color = clBtnFace
    Font.Charset = DEFAULT_CHARSET
    Font.Color = clWindowText
    Font.Height = -11
    Font.Name = 'MS Sans Serif'
    Font.Style = []
    OldCreateOrder = False
    PixelsPerInch = 96
    TextHeight = 13
    object Button1: TButton
    Left = 54
    Top = 264
    Width = 75
    Height = 25
    Caption = 'Button1'
    TabOrder = 0
    OnClick = Button1Click
    end
    object Memo1: TMemo
    Left = 8
    Top = 0
    Width = 185
    Height = 241
    ImeName = '中文(简体) - 搜狗拼音输入法'
    ScrollBars = ssBoth
    TabOrder = 1
    end
    object Button2: TButton
    Left = 56
    Top = 320
    Width = 75
    Height = 25
    Caption = 'Button2'
    TabOrder = 2
    OnClick = Button2Click
    end
    end

  • 相关阅读:
    C# 如何得到局域网中的计算机名?
    设计模式之Factory(转帖)[学习用]
    byte类型特殊的地方
    原码、反码和补码
    由Public key生成Public key token
    .Net位运算符&,|,!,^,<<,>>
    强命名程序集,签名,延迟签名
    把16进制字符转换成byte数组
    SHA1哈希算法
    .NET工具篇(四)—SN.EXE
  • 原文地址:https://www.cnblogs.com/dmqhjp/p/15160804.html
Copyright © 2011-2022 走看看