【问题标题】:Returning an array of pointers?返回一个指针数组?
【发布时间】:2012-08-18 17:22:46
【问题描述】:

我是一名初级程序员,在使用 C++ OOP 时遇到了很多麻烦。具体来说,今晚我试图编写一个简单的类,它接收事件并在多个图像之间切换,并带有一个指向存储在数组中的每个图像的指针。我在尝试创建一个返回指向数组本身的指针的“getter”函数时遇到了一个令人困惑的问题。

基本上,我试图做这样的事情:

class SlideShow
{
public:
    image *getSlideArray();
private:
    image *slideArray[10];
};

所以,我想要一个数组来存储指向每个图像的指针。而且我还想要一个函数来返回数组本身的地址。我在尝试定义 getSlideArray() 函数时遇到了一个问题……我只是不完全确定它为什么不起作用……

这是我最初尝试的,在我的班级的源文件中:

image *SlideShow::getSlideArray()
{
    return this->slideArray;
}

在这次尝试中,编译器不断提出使用“this”关键字的问题,说我试图返回的不是先前指定的类型。但是,到目前为止,这是我编写 getter 函数的方式,并且它通常在使用简单变量时起作用......我怀疑这里存在一些问题,因为 'this' 是一个指针, 和'slideArray' 是一个指向也包含指针的数组的指针......但我很糟糕,这种引用级别现在让我头疼。我花了一段时间才对指针有一个基本的了解,使用地址 & 运算符进行引用等。指向指针和指针数组的指针更令人困惑。

我还应该提到我找到了一种解决方法,我的代码可以在其中编译。 (虽然我还不能真正运行它来检查它是否在运行时工作..)我的工作涉及将定义/返回语句添加到类声明本身(在头文件中):

class SlideShow
{
public:
    image *getSlideArray() {return *slideArray;);
private:
    image *slideArray[10];
};

现在。这编译正确......但是,这也让我感到困惑。我知道,通常,当您返回一个数组(例如,一个整数数组)时,您将返回数组的第零个插槽的地址。但是,如果我试图返回一个 intArray[5],那么在返回它时,我会简单地写 'intArray',对吗?本质上,我对为什么在这种情况下必须在“slideArray”之前添加 * 感到困惑......

所以无论我尝试哪种方式,它都会让我感到困惑。我知道这里有一些“技巧”,它可能与返回指向指针的指针或其他东西有关,但我自己无法解决。我真的很希望学习这个主题,以便我可以开始掌握编程,尤其是 OOP...

谁能帮助我更好地理解这一点?

【问题讨论】:

标签: c++ arrays oop pointers return


【解决方案1】:

你的第一种方法失败了,因为你在函数中给出了错误的返回类型,你应该使用image**

image **SlideShow::getSlideArray()
{
    return this->slideArray;
}

但一般来说,返回类的私有部分是一个非常糟糕的主意,因为它违反了封装规则。在这里,没有什么可以阻止调用代码在数组末尾迭代并崩溃。我认为最好编写带有边界检查的特定访问器函数,如getImage(int i)setImage(int i, image *img),甚至重载[] 运算符。总而言之,我认为这样编写这段代码会更好:

class SlideShow
{
public:
    image *getImage(int i);
    void setImage(int i, image *img);
private:
    image *slideArray[10];
};

image *SlideShow::getImage(int i)
{
    if (i >= 0) && (i < 10)
        return slideArray[i];
    else
        // throw exception
}

void SlideShow::setImage(int i, image *img)
{
    if (i >= 0) && (i < 10)
        slideArray[i] = img;
    else
        // throw exception
}

注意:您可能还应该考虑 setImage 中已经存在第 i 个位置的图像的情况,但为了简单起见,我省略了它。

【讨论】:

    【解决方案2】:

    我将使用指针或智能指针的标准库容器,并返回它(按值或引用,取决于您的用例)。

    动态尺寸:

    #include <vector>
    
    class SlideShow
    {
    public:
        std::vector<image*> getSlideArray() const {return slideArray; }
    private:
        std::vector<image*> slideArray;
    };
    

    对于静态大小(假设支持 C++11):

    #include <array>
    
    class SlideShow
    {
    public:
        std::array<image*, SOME_SIZE> getSlideArray() const {return slideArray; }
    private:
        std::array<image*, SOME_SIZE> slideArray;
    };
    

    如果您没有 C++11,请尝试使用来自标头 &lt;tr1/arrayboost::arraystd::tr1::array

    【讨论】:

      【解决方案3】:

      我建议您考虑使用标准 C++ 库:容器(例如,std::vector)和智能指针(例如,std::shared_ptr)。

      但如果您想粘贴原始数组:

      class SlideShow {
      public:
          image **getSlides() { return &slideArray_[0]; }
          std::size_t slideCount() { return sizeof(slideArray_)/sizeof(*slideArray_); }
      
      private:
          image *slideArray_[10]; // Array of pointers to images.
      };
      

      客户端代码:

      SlideShow slideshow;
      
      // Fill the slideshow here.
      
      image** slides = slideshow.getSlides();
      for (std::size_t i = 0; i < slideshow.slideCount(); ++i) {
          image *slide = slides[i];
      }
      

      SlideShow 类将指向图像的指针数组公开为指向图像指针的指针。要获取数组的大小,客户端代码应该调用slideCount()成员函数。

      【讨论】:

        【解决方案4】:
        image **SlideShow::getSlideArray()
        {
            return this->slideArray;
        }
        

        可能会工作

        【讨论】:

          【解决方案5】:

          您正在使用的方法定义:

          image *SlideShow::getSlideArray() {
              return this->slideArray;
          }
          

          表示正在返回指向image 的指针。但是,您正试图返回一个 image 数组。你应该这样做:

          image *SlideShow::getSlideArray(int image_idx) {
              return this->slideArray[image_idx];
          }
          

          image **SlideShow::getSlideArray() {
              return this->slideArray;
          }
          

          取决于您是要一起返回所有图像(第二个选项)还是一个接一个(第一个选项)。

          顺便说一句,您根本不需要使用this。下面的代码相当于上面的第二个选项:

          image **SlideShow::getSlideArray() {
              return slideArray;
          }
          

          前面的解释应该可以解决您的问题。但是,与其使用“原始指针”和 C 风格的数组,不如使用 STL 容器(请参阅@juanchopanza 的答案)。

          【讨论】:

          • 谢谢!我想我现在明白了。因为我的数组包含指针,如果我想返回单个 *image 元素,我必须指定数组的特定元素。但是,如果我想返回整个数组,我必须返回一个指向指针的指针.. - 我不得不问一个后续问题:为什么我不需要使用'this'关键字?是因为幻灯片的任何实例都会自动知道返回它自己的成员吗?所以,即使我有多个 SlideShow 对象,每个对象都有它自己的函数副本,并且它“理解”返回它自己的成员? - (感谢您的帮助!!)
          • 当您引用类属性或方法时,大多数情况下编译器能够找到您引用的属性/方法,即使没有使用this。在这些情况下,this 只是可选的(即,使用与不使用没有区别)。在其他情况下,您实际上需要this。检查这些其他问题以获取有关何时实际需要 this 的一些示例:12
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-05-11
          • 2018-08-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-10-02
          • 1970-01-01
          相关资源
          最近更新 更多