我是一名初学程序员,我在使用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];
};
现在。这编译正确......但是,这也让我感到困惑。我知道通常,当你返回一个数组(比如一个int数组)时,你将返回数组的第0个插槽的地址。但是如果我试图返回一个intArray [5],当它返回时,我会简单地写'intArray',对吗?基本上,我并不感到困惑,为什么我必须在'slideArray'之前添加*在这种情况下......
所以无论我尝试做哪种方式,都让我感到困惑。我知道这里有一些'技巧',它可能与返回指针指针或指针的指针有关,但我只是无法自己解决。我真的希望学习这门课程,这样我才能开始掌握编程,尤其是OOP ......
任何人都可以帮助我更好地理解这一点吗?
答案 0 :(得分:7)
您正在使用的方法定义:
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的答案)。
答案 1 :(得分: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::array
中的<tr1/array
或boost::array
。
答案 2 :(得分:2)
image **SlideShow::getSlideArray()
{
return this->slideArray;
}
可能会有效
答案 3 :(得分:2)
你的第一种方法失败是因为你在函数中给出了错误的返回类型,你应该使用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个位置已经存在图像,但为了简单起见我省略了它。
答案 4 :(得分: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()
成员函数。