none
CLRでの、外部変数の宣言について RRS feed

  • 質問

  • .NET2005 VISTA です。

    独学でCLIの勉強を始めたのですが、いきなりつまずきました。

     

    1.クラス全体で使う変数の宣言と定義はどこでやるのでしょうか。

      たとえばForm1.h 、で使う場合について、あちこちに宣言を置いてみたのですが、

      置き場所によっては、

     

      「グローバルまたは静的変数は、マネージ型 'cli::array<Type,dimension> ^' を

       含むことはできません」

     

      というエラーになります。

     

      宣言と初期化は、2次元配列で、下記のようにやりました。

     

         array<String^, 2>^ ss = gcnew array<String^, 2>(2, 2){

                              {"**","**"}, {"**","**"},  };

     

      ネットで検索すると、CLIでグローバル変数は使えない、とか、宣言と初期化を

      同時にしては  いけない、というような書き込みがありました。

      宣言と初期化が同時にできない場合、定義は、ss[0,0]="**" から、ひとつづつ

      コーディングしていかないといけないのでしょうか。

      また、どこに書き込むのかも分かりません。

      それとも、そもそもグローバル変数というものが存在しないのでしょうか

     

     

    2.関連してですが、外部変数の宣言のやり方も分かりません。

      外部変数が望ましくない、という問題は別として、一応知っておきたいと思いました。

     

      MFCなら、***view.cpp で宣言して、***.h で extern をつければ外部変数になると

      思うのですが。。。

     

     

    3.もし外部変数が使えない場合、クラス間の値のやり取りは、構造体やクラスで

      行うのでしょうか。

     

     

    アドバイスをお願いいたします。

    2007年12月23日 20:42

すべての返信

  • あくまで一例

    コード ブロック

    // global.h

    #ifndef GLOBAL_H__
    #define GLOBAL_H__


    ref class Global {
    public:
     static array<System::String^,2>^ ss;
    private:
     static Global();
    };


    #endif

     

    コード ブロック

    // global.cpp

    #include "stdafx.h"
    #include "global.h"

     

    static Global::Global() {
      ss = gcnew array<System::String^,2>{ {"0-0","0-1"}, {"1-0","1-1"},  };
    }

     

    コード ブロック

    // 使い方: Form1.h

    #include "global.h"

    namespace Demo {

     

      public ref class Form1 : public System::Windows::Forms::Form {

        ...

      private: System::Void Form1_Load(System::Object^  sender, System::EventArgs^  e) {
         this->textBox1->Text = Global::ss[0,1];
        }
      };
    }

     

     

     

    2007年12月24日 7:00
  • επιστημηさん、ありがとうございます。

     

    globalというサブクラスを、「クラスの追加」ウイザードの、テンプレート「インストーラクラス」で作り、ご提示のコードをコピペしたところ、Form1.hで値を取得できました。

    ただ、CLRを始めたばかりで、まだ基本的な部分が理解できていません。

     

    こうした場合のサブクラスは、「インストーラクラス」でいいのでしょうか。

     

    というか、ソリューションエクスプローラで、global.hをダブルクリックすると、

    「クラスglobalは、デザインできますが、ファイルの最初のクラスではありません」

    という、エラーになるので、間違っていると思うのです。

    (ビルドや実行はできます。)

     

    「インストーラクラス」にした理由は、順番に試したところ、Windowsフォームですとフォームができてしまうし、コンポーネントクラスはまた違う感じで、他に選択肢がなかったからです。

     

    いろいろ検索してみたのですが、よく分かりません。

    本も何冊か買いこんできたのですが、サブクラスのことまで出ていません。

    そもそも「サブクラス」の意味が、MFCと少し違うような気がします。

     

    アドバイスをお願いしたします。

    2007年12月24日 18:47
  • > こうした場合のサブクラスは、「インストーラクラス」でいいのでしょうか。

     

    知りません。 「新しい項目の追加」で .h/.cpp を追加していますから。

     

    > そもそも「サブクラス」の意味が、MFCと少し違うような気がします。

     

    あなたの頭の中までは読み取れません。

    "導出クラス"の意味ですか? だとすると基底クラスは何ですか?

     

    2007年12月24日 21:34
  • ありがとうございます。

     

    >> こうした場合のサブクラスは、「インストーラクラス」でいいのでしょうか。

    >知りません。 「新しい項目の追加」で .h/.cpp を追加していますから。

     

     「新しい項目の追加」で .h/.cpp を追加できることを確かめました。

     

    ネットで検索すると、コンポーネントとクラスを同義のように書いてあるサイトがいくつかあり、イコールなのかもしれないと思いました。

    ただ、親クラスについて、書き込む場所がなどこなのか、よく分かりません。

     

    たとえば、 「新しい項目の追加」で .h/.cpp を追加した場合、そのクラスの親クラスは何なのか、わかりません。

    また、たとえばボタンを貼り付けた場合に、そのボタンのクラスをサブクラスに置き換える方法も分りません。

     

    アドバイスを頂けませんでしょうか。

    2007年12月25日 6:46
  • 1> 「新しい項目の追加」で .h/.cpp を追加した場合、そのクラスの親クラスは何なのか、わかりません。

    2> ボタンを貼り付けた場合に、そのボタンのクラスをサブクラスに置き換える方法も分りません。

     

    ごめんなさい、何がわからないのかわかりません。

     

    1. ref class Derived : Base { ... }; であれば、Derivedの親クラスはBaseです。
    2. なぜ置き換えるの?最初っからサブクラスを貼ればいいじゃない。 って思います。

    2007年12月25日 7:01
  • ありがとうございます。

     

    たとえば、

     

     public ref class global : public System::Configuration::Install::Installer

     

    である場合、親クラスはConfigurationなのでしょうか。

     

     

    MFCの場合、特定のボタンに特別な「振舞い」をさせるとき、

    CButtonクラスを、サブクラスのCmyButtonクラスに置き換えて、

    CmyButtonクラスのソースファイルにコードを書いたりすると思うのです。

     

    CLRでは、そうしたことはないのでしょうか。

     

    まだ、始めたばかりで、全く「手さぐり」の状態なので、見当はずれなのかも

    しれませんが。。。

     

    2007年12月25日 8:58
  • > public ref class global : public System::Configuration::Install::Installer

    > である場合、親クラスはConfigurationなのでしょうか。

     

    System::Configuration::Install::Installer です。

     

    > CButtonクラスを、サブクラスのCmyButtonクラスに置き換えて、

    > CmyButtonクラスのソースファイルにコードを書いたりすると思うのです。

    > CLRでは、そうしたことはないのでしょうか。

     

    「手さぐり」ついでにやってみてはいかがでしょう。

     

    2007年12月25日 10:42
  • επιστημηさん、ありがとうございます。

     

    >> CButtonクラスを、サブクラスのCmyButtonクラスに置き換えて、

    >> CmyButtonクラスのソースファイルにコードを書いたりすると思うのです。

    >> CLRでは、そうしたことはないのでしょうか。

     

    >「手さぐり」ついでにやってみてはいかがでしょう。

     

     

    Windowsフォームでアプリを作り、ボタンを貼り付けました。

     

    System::Windows::Forms::Button^

     

    がボタンのクラスと仮定して、コンポーネントでCmyButtonクラスを作り、

     

    public ref class CmyButton :  public System::ComponentModel::Component

     

    の、public System::ComponentModel::Component を

     

    System::Windows::Forms::Button^ に置き換えてみましたが、ビルドしようとすると、

    エラーだらけになります。

     

    そのほか、コピペする文字列を変えてやってみましたが、うまくいきませんでした。

     

     

     

    2007年12月25日 18:49
  • > public ref class CmyButton :  public System::ComponentModel::Component

    > の、public System::ComponentModel::Component を

    > System::Windows::Forms::Button^ に置き換えてみましたが、ビルドしようとすると、

    > エラーだらけになります。

     

    単に基底クラスを差し替えただけではエラーになるのは当然です。MFCでも同じでしょ?


    たとえば↓、押すとテキストが変わります。

    コード ブロック

    using namespace System;
    using namespace System::Windows::Forms;

     

    namespace MyControl {

      public ref class MyButton : public Button {
      public:
        MyButton()
          { Click += gcnew EventHandler(this, &MyButton::myClick); }

      private:
        Void myClick(Object^, EventArgs^)
          { Text = L"押したでしょ!"; }
      };
     
    }

     

     

    2007年12月26日 1:54
  • επιστημηさん、ありがとうございます。

     

    申し訳ありません。

    上記のコードブロックは、どこに書き込むのでしょうか。

     

    「新しい項目の追加」でソースファイルとヘッダブァイルを追加してコピペしたり、

    いろいろやってみましたが、分りませんでした。

    2007年12月26日 3:03
  • > 上記のコードブロックは、どこに書き込むのでしょうか。

     

    ...愛想が尽きかけてます orz

    C++もC++/CLIも同じです。
    宣言はヘッダに書いて利用者コードで#includeします。

    > いろいろやってみましたが、分りませんでした。


    わけもわからず"いろいろやって"もムダですよ。
    正直「C++のキホン」ができていないように見受けられます。

     

    2007年12月26日 3:09