创建类的实例时出现问题

时间:2010-11-20 09:22:52

标签: c# winforms visual-studio-2010 stack-overflow

我在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类的代码就是我目前所拥有的一切,还没有为它创建一个特定的构造函数......我认为不需要吗?

无论如何,这里完整是Form1类:

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 个答案:

答案 0 :(得分:5)

看起来你已经以不可能的方式结合了继承和组合。基类Form1类型具有声明为派生Bat类型的字段。此外,它使用字段初始值设定项将其初始化为该类型的 new 实例。很明显,你有一个乌龟问题:当你创建一个Bat(或Form1)时,字段初始化程序将运行 - 这将创建一个实例另一个Bat,其反过来将创建另一个 Bat,依此类推,理论上是无限的。 (在实践中:直到你用完堆栈空间)。

这是一个简单的解决方案,可以解决堆栈溢出问题,但可能不是“大图片”中最合适的设计:

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

请注意此类型不再是Form1的子类;它直接从System.Object继承。现在,Form1Bat类在创建它们的实例时都不会表现出无限递归。

在不知道最终目标的情况下,很难建议最佳修复。我建议你考虑一下设计这些课程的最佳方法。我认为您需要花一些时间来学习C#编程语言,OO设计以及WinForms细节。我认为你实际上想要在这里覆盖OnPaint虚拟方法。

答案 1 :(得分:0)

原因通常会使财产与其支持变量混淆。

有些事情:

public class tmp 
{ 
    private int _x; 

    ...

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

答案 2 :(得分: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)
  {

  }
}