クラスの変数設定方法

解決


まさお  2005-06-10 19:41:27  No: 90351

まさお  と申します。  宜しくお願い致します。

  WinXP Pro SP1, VB6 SP6 です。

  クラス変数(←正式名称判らないので、私の造語です)の設定方法で
お尋ねします。

  Class1 というクラスモジュールは完成しているとします。
  これを標準モジュールのプロシージャで使う場合、多くの参考書では
クラス変数の設定を下記のように書かれています。
    Dim varClass As Class1
    Set varClass = New Class1

  しかし、下記のようにしても、動作的には全く同じように見えます。
    Dim varClass As New Class1

  上記の2種に何か違いはあるのでしょうか?

  以上、宜しくお願い致します。


クラゲ  URL  2005-06-10 20:04:33  No: 90352

同じですよ。

丁寧なコーディングをするなら、
Dim varClass As Class1
Set varClass = New Class1

コード量を減らし、美しさを求めるなら
Dim varClass As New Class1

ですね。


特攻隊長まるるう  2005-06-10 20:35:50  No: 90353

>クラス変数(←正式名称判らないので、私の造語です)
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


まさお  2005-06-10 21:01:11  No: 90354

クラゲさん、特攻隊長まるるうさん、どうもありがとうございました。

  特攻隊長まるるうさん、ご指摘戴いた点は一応は理解しておりましたが、
改めて、再認識できました。

  どうもありがとうございました。


魔界の仮面弁士  2005-06-10 21:06:03  No: 90355

同じではありませんよ。明らかな違いがあります。

>  しかし、下記のようにしても、動作的には全く同じように見えます。
>     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付きで宣言時した場合には、
オブジェクトが空であるかどうかが毎回評価され、
空であった場合に、インスタンスが生成される仕様だからです。


クラゲ  URL  2005-06-10 21:09:21  No: 90356

>魔界の仮面弁士さん

勉強になりました。


じゃんぬねっと  URL  2005-06-10 21:19:45  No: 90357

> これは、オブジェクト変数をNew付きで宣言時した場合には、
> オブジェクトが空であるかどうかが毎回評価され、
> 空であった場合に、インスタンスが生成される仕様だからです。

そうですね。
危険といえば危険なので、わたしは As New を使いません。(VB6では)

Dim cls1 As Class1
Set cls1 = New Class1

です。

# VB2002 以降は As New をバリバリ使えるようになって嬉しいです。


魔界の仮面弁士  2005-06-10 21:35:48  No: 90358

一つ補足しておきますと、先の 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関数をおいて、実験してみてください。


特攻隊長まるるう  2005-06-10 22:10:45  No: 90359

>同じではありませんよ。明らかな違いがあります。
間違った情報を回答して申し訳ありませんでした。m(__)m

>これは、オブジェクト変数をNew付きで宣言時した場合には、
>オブジェクトが空であるかどうかが毎回評価され、
>空であった場合に、インスタンスが生成される仕様だからです。
ヘルプで確認しました。結構いろいろと注意すべき点がある
ようですね。キーワード『参照変数』では調べてたのですが、
辿り付いてませんでした。調べが足りなかったです。

[MSDN ライブラリ Visual Studio 6.0]
└[Visual Basic ドキュメント]
  └[Visual Basic の使用方法]
    └[プログラミング ガイド]
      └[Visual Basic を使ってできること]
        └[各種のコンポーネントを利用したプログラミング]
          └[オブジェクトへの参照の作成方法]
            └[オブジェクト変数の宣言]

…の辺りを一通り読んでおかないといけませんね。
CreateObject との違いなんかも書いてありました。


まさお  2005-06-10 22:17:58  No: 90360

魔界の仮面弁士さん、「解決」にしたにも関わらず、わざわざ追加でご教授
戴き、ありがとうございます。

> 先の例でいえば、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 を使うように致し
ます。


ひろ  2005-06-11 03:22:47  No: 90361

このあたりの話は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 で宣言しておく事でことで回避しました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加