フォーラム


ゲスト  

ようこそ ゲスト さん。このフォーラムに投稿するには 登録が必要です。

ページ: [1]
トピック: レコードの演算子オーバーロード
3ma
メンバー
投稿数: 11
レコードの演算子オーバーロード
on: 2019/02/27 18:25 Wed

的当な場所が見つからなかったため、ここに投稿します。
よろしくお願いします。

0-360度を定義する高度なレコード型を作っています。

  ///  <summary>0-360度 角度</summary>
TDegree = record
private
FValue: Double;
public
class operator Implicit(Deg: Double): TDegree; overload;
// class operator Implicit(Deg: TDegree): Double; overload;
// class operator Implicit(Deg: TDegree): Extended; overload;
class operator Implicit(Deg: TDegree): Real; overload;
//
class procedure DegToDMS(Deg: TDegree; var D, M, S, mS: WORD); static;
end;

 
こんな感じです。

で、度を度分秒に分解したいとこんなのを定義

class procedure TDegree.DegToDMS(Deg: TDegree; var D, M, S, mS: WORD);
var
v: Double;
begin
D := Trunc( Deg );  // 整数部は度
v := Frac( Deg ); // 少数部を取り出して分秒の算出準備
end;

 
しかし、

D := Trunc( Deg );

 
にて
E2015:この型には指定した演算子は使えません。
が出ます。

ここをコメントアウトすると、コンパイルは通ります。
と言う事は、Frac( Deg ); はOK。

D := Trunc( Deg.FValue );

 
とすると、通ります。

私の考えるに

Implicit(Deg: TDegree): Double;

 
が呼ばれて、

Trunc( Deg { DegがDoubleに変換される } )

 
こうなるのかと思っているわけですけど。

Frac( Deg ); がOKなのに、なぜ、Trunc( Deg ); がダメなのかがわかりません。

何か、私が見落としている所有りますでしょうか。

よろしくお願いいたします。

3ma
メンバー
投稿数: 11
Re: レコードの演算子オーバーロード
on: 2019/02/28 14:51 Thu

お世話になります。3maです。

前記のRecordに以下を追加

class operator Explicit(Deg: Double): TDegree; overload;

class operatr Explicit(Deg: Double): TDegree;
begin
Result.Value := Deg;
end;

 
で、

0. Edit2.Text := TDegree( Edit1.Text.ToDouble ).ToDMSString;

とすると、正しく無い型キャストでコンパイルが通りません。

下記はOKです。
1. Edit2.Text := TDegree( StrToFloat( Edit1.Text ) ).ToDMSString;
2. Edit2.Text := TDegree( Double.Parse( Edit1.Text ) ).ToDMSString;
3. Edit2.Text := TDegree( Edit1.Text.ToDouble() ).ToDMSString;

ToDoubleは内部でDouble.Parseを呼んでるだけなので、2が通って0が通らないのが不思議。
また、0と3の差も理解できません。

何なのでしょうか。。。

DEKO
管理者
投稿数: 2693
Re: レコードの演算子オーバーロード
on: 2019/03/03 18:50 Sun

とりあえず Double でキャストすれば通りますが、

class procedure TDegree.DegToDMS(Deg: TDegree; var D, M, S, mS: WORD);
var
v: Double;
begin
D := Trunc(Double(Deg)); // 整数部は度
v := Frac(Double(Deg)); // 少数部を取り出して分秒の算出準備
end;

  
レコードのメソッド内 (実装部) では暗黙の型変換を期待しない方がよさそうです。

class procedure TDegree.DegToDMS(Deg: TDegree; var D, M, S, mS: WORD);
var
v: Double;
begin
D := Trunc(Deg.FValue); // 整数部は度
v := Frac(Deg.FValue); // 少数部を取り出して分秒の算出準備
end;

 
常に TDegree.Value を参照した方が精神衛生上いいのかもですね。

ページ: [1]
WP Forum Server by ForumPress | LucidCrew
バージョン: 1.7.5 ; ページロード: 0.039 sec.