返回指针数组

Returning an array of pointers?

本文关键字:数组 指针 返回      更新时间:2023-10-16

我是一名初级程序员,在C++OOP方面遇到了不少麻烦。特别是,今晚我试图写一个简单的类,它接收事件并在多个图像之间切换,每个图像都有一个指针存储在一个数组中。当我试图创建一个返回数组本身指针的"getter"函数时,遇到了一个令人困惑的问题。

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

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

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

以下是我最初在课堂的源文件中尝试的内容

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

在这次尝试中,编译器不断提出使用"this"关键字的问题,说我试图返回的不是以前指定的类型。然而,到目前为止,这是我编写getter函数的方式,而且它通常在使用简单变量时起作用。。。我怀疑这里有一些问题,因为"this"是一个指针,而"slideArray"是指向一个也包含指针的数组的指针。。。但我很糟糕,这种程度的参考现在有点超出了我的想象。我花了一段时间才对指针有了基本的理解,使用address&指向指针和指针数组的指针甚至更令人困惑。

我还应该提到,我找到了一个变通办法,在其中编译我的代码。(虽然我还不能真正运行它来检查它在运行时是否有效。)我的解决方案包括将定义/返回语句添加到类声明本身(在头文件中):

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

现在。这是正确编译的。。。但是,这也让我感到困惑。我知道,通常,当你返回一个数组(比如一个int数组)时,你会返回数组第零个插槽的地址。但如果我试图返回一个intArray[5],在返回它时,我只会写"intArray",对吗?从本质上讲,我并不困惑为什么在这种情况下必须在"slideArray"之前添加*。。。

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

有人能帮我更好地理解这一点吗?

您正在使用的方法定义:

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

表示正在返回指向CCD_ 1的指针。但是,您正试图返回一个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容器(请参见@juancapanza的答案)。

我会使用指针或智能指针的标准库容器,并返回它(根据您的用例,通过值或引用)。

动态尺寸:

#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,请尝试使用标头<tr1/arrayboost::array中的std::tr1::array

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

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

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

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个位置上已经有图像的情况,但为了简单起见,我放弃了它。

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

可能工作

我建议您考虑使用标准C++库:容器(ex,std::vector)和智能指针(ex,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()成员函数。