2012-08-23 136 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個位置的圖像,但我中省略爲了簡單起見。