Equal operator/pointer/deconstructor problems.

Basically, I'm using SDL, and I've made a wrapper class for an SDL_Surface - basically an data structure which holds pixel data. I call this class a DrawSurface. The thing is, all the "make sdl surface" commands return a pointer to an SDL_Surface, so DrawSurface stores a pointer to an SDL_Surface. That's fine and all, but whenever I use the default equal operator:
DrawSurface foo=DrawSurface(constructor to make an image);
DrawSurface bar=foo;

now, the /pointers/ are the same, so they point to the same data. This is a problem, because in the deconstructor of DrawSurface, I need to deallocate the surface. The result is that a surface gets deallocated twice! How can I get around this?!
1
2
3
4
5
6
~DrawSurface() {
    if (sdl_surface_ptr != 0) {
        delete sdl_surface_ptr;
        sdl_surface_ptr = 0;
    }   
}
there are two different pointers.
I suppose I could say something like

1
2
3
4
5
6
~DrawSurface() {
    if (sdl_surface_ptr!=0 && sdl_surface_ptr->some_flag != true) {
        delete sdl_surface_ptr;
        sdl_surface_ptr->some_flag = true;
    }   
}



but then, still, if I allocated stuff like above:
DrawSurface foo=DrawSurface(constructor to make an image);
DrawSurface bar=foo;
and drew a dot on "bar", "foo" would also change. I want them to be copied.
Last edited on
So you want a copy of the data pointed by sdl_surface_ptr?
Mackabee's solution is a bad idea. A temporary copy's dtor would destroy your surface while other objects are still using it. Plus they would still have non-null pointers to surfaces that no longer exist.

Solutions here depend on what behavior you want.

Typically you have 3 options:

Option 1) Prevent object copying completely.

Do this by making the copy ctor and assignment operator private, and don't give them a body:

1
2
3
4
5
6
7
class DrawSurface
{
//...
private:
  DrawSurface(const DrawSurface&);  // don't give it a body
  void operator = (const DrawSurface&);  // don't give it a body
};


Now if you try to copy an object, the compiler will give you an error saying the object can't be copied.


Option 2) Copy the image.

This is accomplished by writing a proper copy ctor and assignment operator:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class DrawSurface
{
//...
public:
  DrawSurface(const DrawSurface& r)  // the copy ctor
  {
    // paraphrasing here, I don't remember the exact SDL functions:

    sdl_surface_ptr = SDL_CreateSurface( /* get surface info from 'r' */ );
    SDL_BlitSurface( /* copy the whole surface */ );
  }

  // the assignment operator
  DrawSurface& operator = (const DrawSurface& r)
  {
    // note this isn't exception safe, but you probably don't need that:
    SDL_DestroySurface( sdl_surface_ptr );

    sdl_surface_ptr = SDL_CreateSurface( /* get surface info from 'r' */ );
    SDL_BlitSurface( /* copy the whole surface */ );

    return *this;
  }
};


Option 3 is to reference count DrawSurface and do copy-on-write semantics, but that's too much coding for an example here. It sounds like you want option 2 anyway.
Topic archived. No new replies allowed.