代码之家  ›  专栏  ›  技术社区  ›  Saladin Akara

创建类实例时出现问题

  •  2
  • Saladin Akara  · 技术社区  · 14 年前

    我在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 回复  |  直到 14 年前
        1
  •  5
  •   Ani    14 年前

    看来你已经以一种不可能的方式将继承和组合结合起来了。基地 Form1 类型具有声明为派生的字段 Bat 类型。此外,它使用字段初始值设定项将其初始化为 新的 该类型的实例。很明显,你一直有一个乌龟问题:当你创造一个 蝙蝠 (或) 形式1 为此,将运行字段初始值设定项-这将创建另一个 蝙蝠 ,这反过来又会产生 另一个 蝙蝠 等等,理论上是无限的。(实际上:直到堆栈空间用完为止)。

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

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

    注意这个类型如何不再是子类 形式1 ;它直接继承自 System.Object . 现在也不是 形式1 也不是 蝙蝠 类在创建实例时将显示无限递归。

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

        2
  •  0
  •   Mitch Wheat    14 年前

    通常,原因是将属性与其支持变量混淆。

    沿着这条线的东西:

    public class tmp 
    { 
        private int _x; 
    
        ...
    
        public int X(x)
        {
            X = x;
        }
    
        3
  •  0
  •   Michael Shaw    14 年前

    你有一个简单的问题。

    您的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)
      {
    
      }
    }