2010-11-20 2 views
2

のインスタンスを作成:問題私は、Visual Studio 2010年には以下のクラスを作成しましクラス

public class Bat : Form1 
    { 
     public int BatLocation; 

     public void draw() 
     { 
      Pen batPen = new Pen(Color.Black); 
      batPen.Width = 10; 
      playArea.DrawRectangle(batPen, BatLocation, (picPlayArea.Height - 30), 50, 10); 
     } 
    } 

をしかし、私はクラスのインスタンスを作成しようとすると、私は私を専門家の意見、スタックオーバーフロー例外を取得無限ループまたは無限再帰を持たないようにしてください。私は以下のように、インスタンスに二つの異なる方法を作成しようとした:

Bat bottomBat; 
bottomBat = new Bat(); 

Bat bottomBat = new Bat(); 

しかし、私はプログラムを実行しようとすると、両方の方法は、同じエラーを返します。また、public修飾子の有無にかかわらずクラス定義を試しました。

私はプログラミングに慣れていないので、何がこの問題を引き起こしているのか分かりません。私は何か間違っているのですか?

編集:Batクラスのコードは、現時点では私が持っているすべてです、それのための特定のコンストラクタを作成していない...私は必要だと思いませんでしたか?

public partial class Form1 : Form 
    { 
     // Define various objects for the game 
     public Graphics playArea; 
     Bat bottomBat = new Bat(); 


     public Form1() 
     { 
      InitializeComponent(); 

      // Create instances of objects 
      playArea = picPlayArea.CreateGraphics(); 
      //bottomBat = new Bat(); 

      // Delegate the mouseMove event for picPlayArea 
      picPlayArea.MouseMove += new MouseEventHandler(picPlayArea_MouseMove); 


     } 

     private void picPlayArea_MouseMove(object sender, MouseEventArgs e) 
     { 
      bottomBat.Location = e.X; 
     } 

     private void btnExit_Click(object sender, EventArgs e) 
     { 
      string msg = "Are you sure you want to exit?", 
        title = "Confirm Exit"; 

      DialogResult res = MessageBox.Show(msg, title, MessageBoxButtons.YesNo, MessageBoxIcon.Question); 
      if (res == DialogResult.Yes) 
      { 
       Environment.Exit(0); 
      } 
     } 

     private void timer1_Tick(object sender, EventArgs e) 
     { 
      // This is where most of the functionality is executed within the game 
      playArea.Clear(Color.White); 
     } 

     private void btnStart_Click(object sender, EventArgs e) 
     { 
      timer1.Enabled = true; 
     } 
    } 
+3

十分な情報がここにありません。ただし、例外的な状況で、あなたはこのように、この問題を解決することができます。クラスのすべてのコンストラクタだけでなく、そのベースクラスのコンストラクタのコードを投稿できますか? (あなたがBCLクラスであるベースクラスにヒットしたら停止することができます) – Ani

+0

あなたが投稿したコード( 'playArea'を参照している行を引いたもの)は私のためにうまくいきます。そのため問題は、ポスト。 –

+0

私はForm1クラスのコードを要求通りに追加しました –

答えて

5

あなたが道の不可能一種で、継承と組成を組み合わせています表示されます。基底のForm1型は、導出されたBat型のフィールドが宣言されています。さらに、フィールド初期化子を使用して、そのタイプの新しいインスタンスに初期化します。明らかに、タートルズ・オール・ザ・ウェイ・ダウンの問題があります。Bat(またはそれにつきForm1)を作成すると、フィールド初期化子が実行されます。これにより別のBatのインスタンスが作成されます。まだをもう1つBatなどと、理論的には無限に作成します。 (実際には、スタックスペースを使い果たすまで)。

はここでスタックオーバーフローの問題を解決する必要があります簡単な修正ですが、「ビッグ・ピクチャー」の中で最も適切な設計ではないかもしれない。このタイプは、もはやForm1をサブクラス方法

public class Bat 
{ 
    public void Draw(Graphics playArea) 
    { 
     ... 
    } 
} 

は注意してください。 System.Objectから直接継承します。現在、Form1クラスとBatクラスのインスタンスが作成されても無限再帰が発生することはありません。

ベストはここで最終的な目的を知らずに修正することは難しいです。私はあなたがこれらのクラスを設計する最良の方法を考えることをお勧めします。 C#プログラミング言語、オブジェクト指向設計、WinFormsの仕様について学ぶ時間を費やす必要があると思います。私はだと思います。実際にはOnPaint仮想メソッドを上書きしようとしています。

+0

その場合、Form1内の 'playArea'オブジェクトにどのようにアクセスできますか?私は既に公開していますが、 ':Form1'を' Bat'クラスから削除すると、その変数にアクセスできなくなります。 –

+1

@Saladin:あなたの 'Bat'クラスの' Form1'のインスタンスを通して 'playArea'オブジェクトにアクセスする必要があります。例: 'myForm1.playArea' –

+0

@Saladin BatがForm1を拡張した場合、作成されたバットは*自分自身の* playAreaを参照してください。 –

0

多くの場合、原因はそのバッキング変数とプロパティを混乱さ:

はとにかく、ここにその全体がForm1クラスです。線に沿って

何か:

public class tmp 
{ 
    private int _x; 

    ... 

    public int X(x) 
    { 
     X = x; 
    } 
0

あなたは単純な問題があります。

クラスBatはForm1から派生し、Form1ではBatの新しいインスタンスを作成します。これはForm1に基づいており、Bat ....という新しいインスタンスを作成します。したがって、スタック空間が使い果たされる。

一般に、Form1はおそらくクラスBatについて知ってはいけません。また、Batについて知る必要があるすべてのコードはBatクラスに属している必要があります。

partial class Form1 
{ 
    public Form1(Bat _bat) 
    { 
    mBat = _Bat; 
    } 

    protected Bat mBat; 
} 

とバットクラスの

public class Bat : Form1 
{ 
    public Bat() : base(this) 
    { 

    } 
} 
関連する問題