5

我是一个初级程序员,我在 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 ......

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

4

5 回答 5

9

您正在使用的方法定义:

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

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

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

或者

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

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

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

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

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

于 2012-08-23T08:23:41.263 回答
4

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

对于动态大小:

#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,请尝试使用std::tr1::arrayfrom header<tr1/arrayboost::array.

于 2012-08-23T08:23:55.083 回答
3

您的第一种方法失败了,因为您在函数中给出了错误的返回类型,您应该使用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
}

Note: you should probably also consider case in setImage where there already is an image on i-th position, but I ommited it for sake of simplicity.

于 2012-08-23T08:48:00.827 回答
2
image **SlideShow::getSlideArray()
{
    return this->slideArray;
}

可能会工作

于 2012-08-23T08:23:45.417 回答
1

我想建议您考虑使用标准 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()成员函数。

于 2012-08-23T08:33:14.650 回答