2012-08-23 97 views
2

我是一个开始的程序员,我一直在C++ OOP方面遇到了一些麻烦。具体来说,今天晚上,我试图编写一个简单的类,它接受事件并在多个图像之间切换,并指向存储在数组中的每个图像。当尝试创建一个返回指向数组本身的指针的getter函数时,我遇到了一个令人困惑的问题。返回指针数组?

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

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

所以,我想有存储指向每个图像阵列。我也想有一个函数返回数组本身的地址。我试图定义getSlideArray()函数时遇到了一个问题...我只是不完全确定它为什么不能正常工作...

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

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

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

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

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

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

所以不管我用哪种方式尝试做,它都让我感到困惑。我知道这里有一些'技巧',它可能与返回指向指针或指针的指针有关,但是我只是无法自己完成。我真的很希望学习这个主题,以便我可以开始掌握编程,特别是OOP ...

任何人都可以帮助我更好地理解这一点吗?

+0

类幻灯片错误 - 检查大括号。 – Abhineet

+0

请尝试http://www.cplusplus.com/doc/tutorial/pointers/和http://www.cplusplus.com/forum/beginner/6644/ – Abhineet

回答

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答案)。

+0

谢谢!我想我现在明白了。因为我的数组持有指针,如果我想返回一个* image元素,我必须指定数组的特定元素。但是,如果我想返回整个数组,我必须返回一个指向指针的指针。 - 我必须问一下后续行为:为什么我不需要使用'this'关键字?是否因为幻灯片的任何实例自动知道返回它自己的成员?因此,即使我有多个SlideShow对象,每个对象都有自己的函数副本,并且“理解”返回它自己的成员? - (感谢您的帮助!!) – MrKatSwordfish

+1

当您引用类属性或方法时,即使未使用this,大多数情况下编译器都能找到您引用的属性/方法。在这些情况下,'this'只是可选的(即使用它或不使用它们)。在其他情况下,你实际上需要'this'。检查这些其他问题的一些例子,当'this'实际上是必要的:[1](http://stackoverflow.com/questions/577243/is-there-any-reason-to-use-this),[2] (http://stackoverflow.com/questions/2337540/when-should-you-use-the-this-keyword-in-c)。 – betabandido

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

可能会工作

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/arrayboost::array

1

我想推荐你考虑使用标准C++库:容器(例如,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()成员函数。

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个位置的图像,但我中省略为了简单起见。