繁体   English   中英

C ++使用指针向Vector添加对象

[英]C++ Adding Objects with pointers into Vector

我有一个向量添加包含SDL_Surface指针的对象作为数据成员,这意味着我必须使用复制构造函数来实现指针的深层复制。 该对象释放析构函数中的表面(指针),这就是问题发生的地方。 当对象被添加到向量中时(通过按下按钮)程序崩溃但是当我从析构函数中SDL_FreeSurface(surface) (内存泄漏)时,当我将对象添加到向量时程序不会崩溃。 如何将对象正确添加到向量中? 有些人可能认为问题在于析构函数试图删除悬空指针,但是在向量中创建对象时会发生错误。

class Block{

  public:

     Block(int x, int y, MediaFunctions &M_Functions);

     Block(const Block& source);

    ~Block();

  private:


    SDL_Surface *block_surface_names;
    SDL_Surface *block_surface_hours;

    SDL_Surface *block_names_detected;
    SDL_Surface *block_hours_detected;

    SDL_Rect     block_rect_names;
    SDL_Rect     block_rect_hours;


    };



    ////////////////////

   Block::Block(int x, int y, MediaFunctions &M_Functions){

      block_surface_names  = M_Functions.LoadOptimizedImage("block_names.png");
      block_surface_hours  = M_Functions.LoadOptimizedImage("block_hours.png");

      block_names_detected = M_Functions.LoadOptimizedImag("block_names_detected.png");
      block_hours_detected = M_Functions.LoadOptimizedImag("block_hours_detected.png");




      block_rect_names.x = x;
      block_rect_names.y = y;
      block_rect_names.w = block_surface_names -> w;
      block_rect_names.h = block_surface_names -> h;


      block_rect_hours.x = block_rect_names.x + block_rect_names.w;
      block_rect_hours.y = block_rect_names.y;
      block_rect_hours.w = block_surface_hours -> w;
      block_rect_hours.h = block_surface_hours -> h;



     }

     //copy
     Block::Block(const Block& source) 
     {
     block_surface_names  = source.block_surface_names;
     block_surface_hours  = source.block_surface_hours;

     block_names_detected = source.block_names_detected;
     block_hours_detected = source.block_hours_detected;

     }


    Block::~Block(){
     //having this is necessary obviously- crashes program
     //removing this causes the program not to crash

     SDL_FreeSurface(block_surface_hours);
     SDL_FreeSurface(block_surface_names);

     SDL_FreeSurface(block_hours_detected);
     SDL_FreeSurface(block_names_detected);

    }


    //where the object with SDL_FreeSurface() in the dtor is added to vector - crash!
   void Control::HandleEvents(SDL_Event &event, MediaFunctions &M_Functions){

       if(event.type == SDL_KEYDOWN){
           if( event.key.keysym.sym == SDLK_a )

            //append a block instance using copy constructor
            BlockVector.push_back(Block (Block(100,100, M_Functions) ) );

       }

     }

你的代码:

BlockVector.push_back(Block (Block(100,100, M_Functions) ) );

看起来非常不理想,它会创建看似需要一些时间加载的不必要的数据副本,我的意思是在Block::Block()加载这个png。

您可以做的最好的事情是使BlockVector成为:

 std::vector<boost::shared_ptr<Block>> blocks;

这样你就不需要制作不必要的Block副本了。 否则你需要在Block类中为你的SDL_Surface*指针添加引用计数,这也可以用shared_ptr和自定义删除器完成(在这里看看: make shared_ptr不能使用delete )。

复制构造函数应该进行深层复制,但是你的不是。 幸运的是,你根本不需要复制构造函数,只需要一个移动构造函数。

 Block::Block(Block&& source) 
 {
 block_surface_names  = source.block_surface_names;
 block_surface_hours  = source.block_surface_hours;
 source.block_surface_names = NULL;
 source.block_surface_hour = NULL;

 block_names_detected = source.block_names_detected;
 block_hours_detected = source.block_hours_detected;
 source.block_names_detected = NULL;
 source.block_hours_detected = NULL;
 }

只与你的问题含糊不清:

BlockVector.push_back(Block (Block(100,100, M_Functions) ) );

这使得一个Block ,然后复制该Block ,然后将该块的副本推送到该向量上。 但是,可以使用以下代码直接在向量中创建Block

BlockVector.emplace_back(100, 100, M_Functions);

如果你没有启用C ++ 11的编译器,你最好使用boost::shared_ptrvector ,它比这段代码更慢,更复杂,但也可以解决问题。 在任何一种情况下, Block类都应该有一个已删除(或未定义)的复制构造函数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM