2014-04-13 86 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