[Delphi:90309] 列挙型の派生?

298 views
Skip to first unread message

maga...@mailpost.jp

unread,
Feb 28, 2008, 7:43:41 PM2/28/08
to Del...@ml.users.gr.jp
皆様 いつもお世話になっております 柴田と申します

文法?について教えてください

type
TMyMode = (
mmNormal1,
mmNormal2,
mmNormal3
);

TMyModeEx = (
mmNormal1, ←
mmNormal2, ← この部分にTMyModeの要素を含めたい
mmNormal3, ←
mmExpert1,
mmExpert2
);

クラス派生のようにメンバ(要素)を増やして再定義したいのです。
皆さんならどういたしますでしょうか?


高木太郎

unread,
Feb 28, 2008, 8:25:43 PM2/28/08
to Del...@ml.users.gr.jp
いつもお世話になっております。 イマジオムの高木です。

柴田さん:

> クラス派生のようにメンバ(要素)を増やして再定義したいのです。
> 皆さんならどういたしますでしょうか?

> type
> TMyMode = (
> mmNormal1,
> mmNormal2,
> mmNormal3
> );
>
> TMyModeEx = (
> mmNormal1, ←
> mmNormal2, ← この部分にTMyModeの要素を含めたい
> mmNormal3, ←
> mmExpert1,
> mmExpert2
> );

 私なら、拡張される可能性があるものには列挙型を使わないようにします。

type TMyMode=LongInt;

const mmNormal1=$0001;
mmNormal2=$0002;
mmNormal3=$0003;


type TMyModeEx=TMyMode;

const mmExpert1=$0101;
mmExpert2=$0201;

列挙型は、とどのつまり値の意味づけです。 上記の書き方であれば、
何となく型や、値の変域を継承しているように見えますので、目的は
達成できます。 $???? の部分は、値が重複しないようにしてください。

 #わざと値を重複させて複数の意味を持たせるというテクニックも
  ありますが、今回は割愛します。


 ちなみにもとの TMyMode の定義に手を入れることができない場合……

type TMyMode=(mmNormal1,
mmNormal2,
mmNormal3);


type TMyModeEx=TMyMode;

const mmExpert1=TMyModeEx($0101);
mmExpert2=TMyModeEx($0102);

……などとしても似たようなことはできます。
――――――――――――――――――――――――――――――――――――
株式会社イマジオム 代表取締役 高木太郎
〒316-0024 茨城県 日立市 水木町 1-11-10
電話:0294-28-0147
ファクシミリ:0294-28-0148
電子メール:tarou_...@imageom.co.jp
ホームページ:http://www.imageom.co.jp/


狐小僧太郎吉

unread,
Feb 29, 2008, 8:39:34 PM2/29/08
to Del...@ml.users.gr.jp
>
> type
> TMyMode = (
> mmNormal1,
> mmNormal2,
> mmNormal3
> );
>
> TMyModeEx = (
> mmNormal1, ←
> mmNormal2, ← この部分にTMyModeの要素を含めたい
> mmNormal3, ←
> mmExpert1,
> mmExpert2
> );
>

コンパイラを改造しないと無理なようですが
代替案として、こんなんどうですか

TOrigMode =
(
mmNormal1 = 1,
mmNormal2 = 2,
mmNormal3 = 3,
mmExpert1 = 4,
mmExpert2 = 5
);


TMyMode = mmNormal1..mmNormal3;

TMyModeEx = mmNormal1..mmExpert2;

ちなみに、列挙型は、ファイルに書き出す時のことを考慮して
数値を明示しておいたほうが無難かと思います
また、列挙型の数値のサイズは、自動的に決定
されるようで、
上の場合
aa :TMyMode;
と宣言すると
1バイトが確保されるようです

コンパイラオプション
$MINENUMSIZE 4
を使用してサイズを調整するか
ダミーで列挙変数を下のように宣言すると

TOrigMode =
(
mmNormal1 = 1,
mmNormal2 = 2,
mmNormal3 = 3,
mmExpert1 = 4,
mmExpert2 = 5,
mmDmmy = $7FFFFFFF
);

とでもすると
4バイトが確保されます

maga...@mailpost.jp

unread,
Mar 1, 2008, 7:54:32 PM3/1/08
to Del...@ml.users.gr.jp
On Fri, 29 Feb 2008 09:43:41 +0900
"maga...@mailpost.jp" <maga...@mailpost.jp> wrote:

高木さん、狐小僧太郎吉さん

列挙型の要素って ただの変数名だったんですね
理解できました。

おかげさまで綺麗なコードが書けそうです。
有難うございました


狐小僧太郎吉

unread,
Mar 2, 2008, 8:56:00 PM3/2/08
to Del...@ml.users.gr.jp
狐小僧太郎吉 wrote:
>
> ちなみに、列挙型は、ファイルに書き出す時のことを考慮して
> 数値を明示しておいたほうが無難かと思います
> また、列挙型の数値のサイズは、自動的に決定
> されるようで、
> 上の場合
> aa :TMyMode;
> と宣言すると
> 1バイトが確保されるようです
>
> コンパイラオプション
> $MINENUMSIZE 4
> を使用してサイズを調整するか
> ダミーで列挙変数を下のように宣言すると
>
> TOrigMode =
> (
> mmNormal1 = 1,
> mmNormal2 = 2,
> mmNormal3 = 3,
> mmExpert1 = 4,
> mmExpert2 = 5,
> mmDmmy = $7FFFFFFF
> );
>
> とでもすると
> 4バイトが確保されます
サイズの確保は $MINENUMSIZEのみを
使用したほうが良いようです。

というのも
列挙型は、配列のインデクスとしても使用できますが、

例えば
aa :array[TOrigMode] of integer;

と宣言し
var ii :TOrigMode;

for ii := Low(TOrigMode] to High(TOrigMode) do
begin
aa[ii] := ~;
end;
という使い方ができますが
上の宣言例のように
mmDummyを指定すると
コンパイラにmmExpert2 から mmDumy
の間に要素があると見なされて
上の配列が巨大な大きさになります。
サイズの確保のために mmDummywo
を使うのは避けたほうが良いようで
また数値を明示する場合は
配列のインデクスに使用するかどうか
一考の余地が必要なようです



maga...@mailpost.jp

unread,
Mar 2, 2008, 10:04:29 PM3/2/08
to Del...@ml.users.gr.jp
ご丁寧に報告頂き有難うございます

>サイズの確保は $MINENUMSIZEのみを
>使用したほうが良いようです。

今回は Delphi2005 for.Net と Delphi5の
混在開発の為、Delphi5に合わせ(列挙値の設定不可らしいです)
狐小僧太郎吉さんの案を元に

TOrigMode = (
mmNormal1,
mmNormal2,
mmNormal3,
mmExpert1,
mmExpert2


);
TMyMode = mmNormal1..mmNormal3;
TMyModeEx = mmNormal1..mmExpert2;

とさせて頂き、GetEnumName や GetEnumValue 等も使う予定です
このまま 列挙値の設定はしない方向ですが
問題ございますでしょうか?


狐小僧太郎吉

unread,
Mar 3, 2008, 7:29:10 PM3/3/08
to Del...@ml.users.gr.jp
maga...@mailpost.jp wrote:
>
> とさせて頂き、GetEnumName や GetEnumValue 等も使う予定です
> このまま 列挙値の設定はしない方向ですが
> 問題ございますでしょうか?
>


問題ないでしょう
どこかで、明示的に宣言しておかないと
プログラム修正したときに、うっかり変わってしまい
実行環境を記録したINIファイル等を
設定するときに使っていると
往生をこきます。

整数値に対応させるには、
いくらでも代替案はあります。
例えば、配列を使って

aa :array[TOrigMode] of integer = (1,2,3,4,5);

とやって、対応させるとか
こっちの方がええかもね
(ちょっち、めんどくさいか)

aa :array[TOrigMode] of integer = (10,20,30,40,50);

とか、+10ずつにするとかできますからな。


ちなみに、私は、Delphi7を使用しております
Delphi2005はインストールしてますが
使ってません。

GetEnumName GetEnumValue については知らなかった
しかし、上のように普通に宣言して

 GetEnumName(TypeInfo(TOrigMode),Ord(mmNormal3));
と書いても

「型情報を持ってません」
とか、エラーが出て使えませんが
VCLで定義してある
TAlignment,TLabelPosition
については、文法エラーがでないで
GetEnumName が使えます。
、VCLのソースを見ても
普通にENUM定義してあるだけなのに
??????????
どないなってんねん
違いが見えない

Reply all
Reply to author
Forward
0 new messages