2014-04-13 118 views
-2

我正在製作一個SDL遊戲,它使用libconfig從文件讀取一些設置。問題是我創建了一個名爲ClipList的類,其中包含一個std::vector<SDL_Rect>來存儲設置,但是當嘗試將SDL_Rect對象添加到該向量時,出於某種原因,push_back什麼都不做,最終得到一個空向量。C++ STD向量push_back似乎不工作

這是類:

class ClipList 
{ 
    public: 
     ClipList(); 
     ClipList(int); 
     virtual ~ClipList(); 
     void addClip(int,int,int,int); 
     void getClip(int,SDL_Rect*); 
     int getLength(); 
    protected: 
    private: 
    std::vector<SDL_Rect> clips; 
}; 
ClipList::ClipList(int l) 
{ 
    clips.reserve(l); 
} 

void ClipList::addClip(int x,int y,int w,int h){ 
    SDL_Rect rect; 
    rect.x = x; 
    rect.y = y; 
    rect.w = w; 
    rect.h = h; 
    clips.push_back(rect); 
} 

void ClipList::getClip(int i,SDL_Rect* rect){ 
rect = &(clips.at(i)); 
} 

int ClipList::getLength(){ 
    return clips.size(); 
} 

而這正是我初始化ClipList對象的功能。這個函數被main調用。

void set_clips(Config* placlips,ClipList* clips, ClipList* flipclips){ 
    const Setting& root = placlips->getRoot(); 
    int x,y,w,h; 
    try{ 
     Setting& clipsett = root["clips"]; 
     int cliplen = clipsett.getLength(); 
     clips = new ClipList(cliplen); 
     flipclips = new ClipList(cliplen); 
     for(int i=0;i<cliplen;i++){ 
      const Setting& c = clipsett[i]; 
      if(!(c.lookupValue("x",x)&&c.lookupValue("y",y)&&c.lookupValue("w",w)&&c.lookupValue("h",h))){ 
       continue; 
      } 
      clips->addClip(x,y,w,h); 
     } 
    }catch(const SettingNotFoundException &nfex){ 
     cerr << "Setting not found at" << nfex.getPath() << endl; 
    } 
} 

不管ClipList對象是否得到mainset_clips初始化,clips.push_back(rect)不起作用。矢量的容量發生了變化,但是沒有對象被存儲,所以如果我試圖對矢量做其他事情,甚至檢查矢量是否爲空,我最終會出現段錯誤。

回答

1

我要去猜測,該功能

void set_clips(Config* placlips,ClipList* clips, ClipList* flipclips); 

的簽名是罪魁禍首。您正在爲此函數中的clipsflipclips分配內存,但由於指針是按值傳遞的,因此調用函數看不到分配的內存。

如果改變函數簽名:

void set_clips(Config* placlips, ClipList*& clips, ClipList*& flipclips); 

你的問題就會消失。

+0

是的,這是問題所在,雖然通過引用傳遞指針得到的代碼來編譯'SDL_Rect'對象仍然沒有被存儲在內存中。我通過初始化'main'中的ClipList對象並通過引用而不是指針傳遞ClipList對象來解決問題。 – Magnus

+0

@Magnus這也是一個很好的解決方案。 –

1

clips.push_back(rect)工作正常。您的set_clips函數會分配新的ClipList實例,但不會將這些指針傳回給調用者。調用者可能試圖使用垃圾指針作爲初始化實例,這就是爲什麼你會得到段錯誤。

您需要將創建的對象傳回。你應該使用std :: shared_ptr> <>來代替裸指針。

你需要跟蹤的所有權和處理異常:

如何做到不使用std :: shared_ptr的<>更新。就實際通過而言,我使用的規則(最初來自Lakos的「大規模C++軟件設計」)是返回值的參數(正如您試圖使用它們的那樣)是指針,而只讀參數是值或常量引用。返回值首先。

所以,你set_clips功能應該是這樣的:

void set_clips(ClipList** clips, ClipList** flip_clips, Config const& placlips) 

當你調用set_clips你一個指針傳遞給每個指針將接收分配的值,並傳遞一個const引用到placlips反對說沒有被函數修改。

你們就這是這樣的:

ClipList* clips = 0; 
ClipList* flip_clips = 0; 
set_clips(&clips, &flip_flips, placlips); 
// ... then do whatever comes next. 

但隨着的std :: shared_ptr的<>或提高組合這些規則:: shared_ptr的<>更好, 「現代C++」 的風格。

+0

如何在沒有shared_ptr的情況下執行此操作? – Magnus