Class dependence design issue

Started by
8 comments, last by ToohrVyk 15 years, 9 months ago
I have two classes, Surface and Brush. The idea is that Surface provides a drawing surface (and handles all the system resources) and Brush does all the drawing on that surface. The way I want to do it is like so. Surface surf(500, 400); // Create a surface of size 500x400 Brush brush(surf); // Create a brush for the surface brush.draw_line(0, 0, 100, 100); // Draw a line from (0, 0) to (100, 100) I have this working quite nicely, but my concern here is that if we create a Brush somewhere and then the Surface gets destroyed, then we have a Brush that points to a Surface that no longer exists. I have two solutions for this. 1) Keep a running list of surfaces that still exist. Then the Brush can check if the surface it points to exists anymore. (This is how I'm doing it now). 2) Create a connection between the Brush and Surface. The Surface keeps track of which Brushes are assigned to it, and alerts them when it gets destroyed. (I was doing this, but switched to (1) after a while because it's simpler). What I'm wondering is which way is better or if there's a better method beyond these two. Connections betweens objects always seem messy in my opinion, so I'm leaning towards (1), but I'm open to other ideas. Thanks.
Advertisement
How about the obvious? Prevent the surface from getting destroyed while there are valid brushes attached to it?

If this is C/C++, you can do that with smart pointers easily
If you have ever heard of reference counting, then that is what you will probably be happy with. Look it up on google. The brush will be able to specify that it is still using the surface.
Denzel Morris (@drdizzy) :: Software Engineer :: SkyTech Enterprises, Inc.
"When men are most sure and arrogant they are commonly most mistaken, giving views to passion without that proper deliberation which alone can secure them from the grossest absurdities." - David Hume
Quote:Original post by Spoonbender
How about the obvious? Prevent the surface from getting destroyed while there are valid brushes attached to it?

If this is C/C++, you can do that with smart pointers easily


If I explicitely destroy the Surface, I want the Surface to be destroyed. I don't want it to stay alive as long as a Brush is using it. So it's not as simple as using a boost::shared_ptr or something like that.

I may end up going with a variation of my (2); although, instead of having the Brush and Surface class handle the connection issues, I may push them into an auxillary connection class.
There's another alternative if you don't want Surface to know about Brush (which is reasonable): event passing.

Have a surface fire an event when it is destroyed, and have a brush listen for those events (register its event handler on creation) and invalidate its pointer when an event is received. boost has signals/slots for this kind of thing.
Couldn't he use a boost::weak_ptr to store the surface address in the brush class? Then every time the brush wants to draw to the surface, he has to check if the pointer is still valid using lock(), for example

if(shared_ptr<Brush> b = q.lock())
{
// do drawing stuff
}

If the surface gets deleted and a brush tried to draw, nothing will happen.
What's wrong with this:
somebrush.draw_line(somesurface, x1, y1, x2, y2);

?
Or, you could simply not worry about it. Seems to work pretty well for STL and iterators. This is C++, where things can blow up, but trying to cover every base simply means a different language is better suited for it. C++ works best where things need to be "fast", or down to metal. For all those cross-referenced, reference counted, event dispatched systems I'd prefer to switch to a different language, all of which do it much better and simpler.

Add a safety check that tests whether surface exists, but that's it.

First however: What is this for? Why is brush standalone class? Why does brush know how to draw a line? What makes brush so special it needs a life on its own? Will it be part of a toolbar?

Hopefully this isn't just wrapper on top of WinAPI drawing resources.
Quote:Original post by the_edd
What's wrong with this:
somebrush.draw_line(somesurface, x1, y1, x2, y2);

?


I think it might get a bit tiring to type somesurface over and over again, especially if I'm drawing more than just a line or two.
Quote:Original post by tendifo
I think it might get a bit tiring to type somesurface over and over again, especially if I'm drawing more than just a line or two.


If you're writing more than just a line or two, you should be using a loop anyway, so you will only write somesurface once.

In the end, I agree with Antheus: the easiest way to do this is to give the brush a local scope, so that it will always be destroyed before the surface is.

This topic is closed to new replies.

Advertisement