【问题标题】:Creating an array of zero width and zero height?创建一个零宽度和零高度的数组?
【发布时间】:2010-11-29 22:14:59
【问题描述】:

我的编程课上有一个作业,非常措辞很糟糕......下面这行真的难倒我。我们正在创建一个名为 FloatArray 的类,其中包含一个数组(arr,它只是指向一堆floats 的指针)。

默认构造函数 FloatArray();应该创建零宽度和零高度的数组。

我不知道我的教授是什么意思……还有其他人吗?我们需要提供另一个构造函数,它指示数组的高度和宽度。这很好,花花公子 - 只需插入数字,然后分配......但他所说的“创建零宽度和零高度的数组”是什么意思?

如你所知,数组简单地定义为:

float *arr;

帮助我理解这种疯狂!如果由我决定,我什至不会为这样的类创建一个空白的构造函数......

无论如何 - 我在这里忽略了什么吗?这是我以前从未遇到过的某种术语,还是我说这是疯狂的说法是正确的?

我应该只在默认构造函数中执行以下操作吗?

*arr = 0;

因为我不能arr = new float[0],现在我可以:P(或者我可以 - 我刚刚尝试过(感谢 Thomas!)它编译并运行......!? )

这是否意味着当我执行arr = new float[0] 时,arr 指向堆上的某个位置(开始?)?

我知道这个问题似乎很模糊,但这就是整个作业的方式 - 措辞非常糟糕。我只是想确定不只是我!

【问题讨论】:

  • "因为我不能做 arr = new float[0],现在我可以:P" 实际上,我认为你可以,我认为这正是你的教授的意思。
  • ...哎呀。我假设内存分配类似于数组(因为你不能声明一个零大小的数组)。声明类似的东西会导致分配 arr 什么?
  • arr 被分配了一个零长度 float 数组的地址。并不是说您可以在其中存储任何东西,但如果需要,您可以安全地delete 它。 (同样,您也可以使用 0 指针来执行此操作。)
  • 把这个作为答案,托马斯。你会得到布朗尼积分!!!

标签: c++ arrays class constructor


【解决方案1】:

本练习可能旨在突出界面表示之间的区别。我不知道FloatArray 类中的其他方法应该是什么,但我怀疑有一些方法可以在数组的特定位置获取和设置元素。

使用这样的默认构造函数,该类应该创建一个作用的对象,就好像它具有零宽度和零高度一样。也就是说,如果调用者随后请求设置数组的特定元素,则该方法应返回通常用于“越界”的任何条件。也就是说,通过抛出异常或错误返回或其他方式。

在内部,类可以通过分配内存来表示这种情况,甚至。也许设置arr = NULL 就足够了,或者它必须指向非空内存,但这取决于你作为类的实现者。关键是界面应该按照作业问题所定义的特定方式运行。

【讨论】:

  • 实际上,为了引用数组中的单个元素(这是一维的,但我们将它作为二维显示给“程序员”),因此 [] 运算符被重载以返回一个位置移动了数组 [x] x 倍的“高度”。
  • 我不喜欢这个作业的设置方式,这样说吧——很多武断的、不必要的步骤来完成非常简单的事情。不过我不是教授!
  • 如果您认为某个步骤是任意的或不必要的,请询问您的导师。要么它真的没有必要,要么它旨在突出手头问题的某些方面。或者它可能为以后的练习奠定基础。
  • 这样说吧,格雷格。你宁愿只声明一个多维数组,还是声明一个单维数组,然后重载 [] 运算符,使对象本身“看起来”像一个多维数组?
  • 在 C++ 中,您不能声明具有两个维度变量的多维数组。所以你将不得不做后者。
【解决方案2】:

我认为他的意思是构造函数不应该为数组初始化任何内存空间。

不过还是问问你的教授吧。

【讨论】:

    【解决方案3】:

    在构造函数中使用*arr = 0 是非常不明智的。由于arr 未初始化,它可能指向任何东西。因此*arr = 0 的意思是“将一些随机内存块设置为0,这可能会失败。另一方面,arr = new float[0]indeed a valid operation

    我建议对 0 大小的数组使用“new float[0]”。这减少了对 0 大小数组的一些特殊处理,例如使用new FloatArray(0) 显式创建的数组,这将导致与new FloatArray() 完全相同的数组。请注意,一个好的替代方法可能是在“常规”构造函数中使用长度参数的默认零值。

    【讨论】:

      【解决方案4】:

      你应该问问你的教授。我怀疑他会在这里看到这个。他可能只是想将其初始化为 null。

      【讨论】:

      • 一开始定义指针的时候不是初始化为null吗?
      • 这将取决于语言或环境。某些语言(如 C#)被指定为在声明变量时对其进行初始化。其他的,比如 C++,不是,但你使用的 IDE 可能会为你做。
      【解决方案5】:

      你可能想要这样的东西:

      #include <exception>
      
      class FloatArray 
      {
      public:
          FloatArray():arr(new float[0]){}
          FloatArray(int width, int height)
          {
              arr=new float[height*width];
              mWidth=width;
              mHeight=height;
          }
      
          ~FloatArray(){ delete [] arr; }
      
          float operator()(int xindex, int yindex)
          {
              if (!isValid(xindex,yindex))
              {
                  throw std::exception();  // Some suitable exception
              }
              return arr[yindex*mWidth+xindex];
          }
      
          bool isValid(int xindex, int yindex);
      
      private:
          float* arr;
          int mWidth;
          int mHeight;
      };
      

      注意事项:
      我离开 isValid() 时没有定义作为练习。
      dtor 对 EDIT: delete [] arr; 无论调用哪个 ctor 都很好。
      我使用operator() 作为访问器。
      除了 std::exception 之外,您还可以抛出其他东西。
      没有 setter 方法 - 留作练习。
      我故意犯了一个我知道的错误。

      【讨论】:

      • 错误会是“delete arr;”吗?这应该是“删除[] arr;” ?
      • 糟糕——好的,我确信有人会发现另一个错误。好吧,也许这就是您的教授所说的-您需要一个必须为delete[] arr; 的dtor,因此默认dtor 中需要arr=new float[0];。查看我的编辑。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-23
      • 1970-01-01
      • 1970-01-01
      • 2016-03-17
      • 1970-01-01
      相关资源
      最近更新 更多