まさお と申します。 宜しくお願い致します。
WinXP Pro SP1, VB6 SP6 です。
クラス変数(←正式名称判らないので、私の造語です)の設定方法で
お尋ねします。
Class1 というクラスモジュールは完成しているとします。
これを標準モジュールのプロシージャで使う場合、多くの参考書では
クラス変数の設定を下記のように書かれています。
Dim varClass As Class1
Set varClass = New Class1
しかし、下記のようにしても、動作的には全く同じように見えます。
Dim varClass As New Class1
上記の2種に何か違いはあるのでしょうか?
以上、宜しくお願い致します。
同じですよ。
丁寧なコーディングをするなら、
Dim varClass As Class1
Set varClass = New Class1
コード量を減らし、美しさを求めるなら
Dim varClass As New Class1
ですね。
>クラス変数(←正式名称判らないので、私の造語です)
Class1 というクラスモジュールを参照した『(オブジェクト)参照変数』
…かな?…ヘルプで調べるとしたらそんなキーワードになります。
[VB6.0]だとフォーム名なんかは呼び出した時点で勝手に New されて
実体化しちゃって混乱する原因になってると思うけど、本来、オブジェクトは
参照変数を用意して、必要な時に New して実体化(インスタンス生成)し、
使用するべきなんでしょうね。…で、動作的には同じなんですけど、処理に
よっては実体化する必要が無い場合がありますよね?。varClass は New
しなければ実体化しませんので、下記処理のキャンセル時には不必要な
メモリ消費を避けられます。Class_Initialize イベントが New の時点で
起こりますので確認して下さい。
[VB6.0]
Private Sub Command1_Click()
Dim varClass As Class1
If MsgBox("処理を続けますか?", vbOKCancel) = vbCancel Then
Exit Sub
End If
Set varClass = New Class1
End Sub
クラゲさん、特攻隊長まるるうさん、どうもありがとうございました。
特攻隊長まるるうさん、ご指摘戴いた点は一応は理解しておりましたが、
改めて、再認識できました。
どうもありがとうございました。
同じではありませんよ。明らかな違いがあります。
> しかし、下記のようにしても、動作的には全く同じように見えます。
> Dim varClass As New Class1
> 上記の2種に何か違いはあるのでしょうか?
たとえば、
Dim C1 As New Class1
Dim C2 As Class1
'Nohingを代入
Set C1 = Nothing
Set C2 = Nothing
If C1 Is Nothing Then
MsgBox "C1は空"
End If
If C2 Is Nothing Then
MsgBox "C2は空"
End If
を実行すると、メッセージが表示されるのは「C2」の方だけです。
これは、オブジェクト変数をNew付きで宣言時した場合には、
オブジェクトが空であるかどうかが毎回評価され、
空であった場合に、インスタンスが生成される仕様だからです。
>魔界の仮面弁士さん
勉強になりました。
> これは、オブジェクト変数をNew付きで宣言時した場合には、
> オブジェクトが空であるかどうかが毎回評価され、
> 空であった場合に、インスタンスが生成される仕様だからです。
そうですね。
危険といえば危険なので、わたしは As New を使いません。(VB6では)
Dim cls1 As Class1
Set cls1 = New Class1
です。
# VB2002 以降は As New をバリバリ使えるようになって嬉しいです。
一つ補足しておきますと、先の C1, C2 のサンプルについては、
「C1 を Nothing にする事ができない」という意味ではありませんので、
その点は誤解しないでください。
先の例でいえば、C1, C2 いずれも Nothing にする事はできていますが、
その後で Nothing状態の C1 にアクセスすると、この時点で Class1 の
インスタンスが自動生成されてしまうため、Nothingかどうかの判定が
行えない、という話です。
このような動作をするため、特に理由が無い限りは、変数宣言時に
Newを付けない方が無難でしょう。(VB.NETであれば問題ありませんけど)
さらに書くならば、Form1, Form2 などといったVB6の暗黙変数も、
まさにこの「New 付きで宣言されたオブジェクト」の状態にあります。
たとえば、以下のようなコードを実行した場合、
If Form2 Is Nothing Then
MsgBox "TEST"
End If
このIf文での判定時に、Form2のInitializeイベントが発生する事になります。
Form2のInitializeイベントにMsgBox関数をおいて、実験してみてください。
>同じではありませんよ。明らかな違いがあります。
間違った情報を回答して申し訳ありませんでした。m(__)m
>これは、オブジェクト変数をNew付きで宣言時した場合には、
>オブジェクトが空であるかどうかが毎回評価され、
>空であった場合に、インスタンスが生成される仕様だからです。
ヘルプで確認しました。結構いろいろと注意すべき点がある
ようですね。キーワード『参照変数』では調べてたのですが、
辿り付いてませんでした。調べが足りなかったです。
[MSDN ライブラリ Visual Studio 6.0]
└[Visual Basic ドキュメント]
└[Visual Basic の使用方法]
└[プログラミング ガイド]
└[Visual Basic を使ってできること]
└[各種のコンポーネントを利用したプログラミング]
└[オブジェクトへの参照の作成方法]
└[オブジェクト変数の宣言]
…の辺りを一通り読んでおかないといけませんね。
CreateObject との違いなんかも書いてありました。
魔界の仮面弁士さん、「解決」にしたにも関わらず、わざわざ追加でご教授
戴き、ありがとうございます。
> 先の例でいえば、C1, C2 いずれも Nothing にする事はできていますが、
> その後で Nothing状態の C1 にアクセスすると、この時点で Class1 の
> インスタンスが自動生成されてしまうため、Nothingかどうかの判定が
> 行えない、という話です。
>
これは非常に参考になりました。
本当にありがとうございました。
私は良く以下のようなことをします。
Dim Cla As Class1
Dim Coll as Collection1 'Class1のCollection
For Each Cla in Coll
IF Cla.ABC = "" Then Exit For
Next
If Not Cla Is Nothing Then
…
End If
もし、As New Class1 にすると、Cla Is Nothing には永久にならない訳
ですネ。
じゃんぬねっとさん、特攻隊長まるるうさん もありがとうございました。
横着せずに Dim … As Class1: Set … = New Class1 を使うように致し
ます。
このあたりの話はActiveX EXEだとさらに面倒ですね
以下余談ですが、
clsA As クラス名
Set clsA = CreateObject("自プロジェクト名.ClassA")
Set clsA = Nothing
If clsA Is Nothing Then
msgbox "is Nothing"
End If
の様な処理で、clsA Is Nothing が原因でクラスインスタンスが生成される
という現象の経験があります。
このときは変数を As Object で宣言しておく事でことで回避しました。
ツイート | ![]() |