C++ - Abuse friends or expose implementation details?

Started by
1 comment, last by MaulingMonkey 18 years ago
I'm working on some engine code, and I have the following setup: An Image class, containing a IDirect3DTexture9 internally A Graphics class, that in order to render an Image, needs to access the DirectX texture. Similiar situations exist with my Font class (ID3DXFont internally), Cursor class (IDirect3DSurface9 internally), and one or two other classes. As far as I can see, my choices are to expose the IDirect3DTexture9 via a getter function or make Graphics a friend of Image. If I use the getter function approach, I can return the IDirect3DTexture9 by constant reference so the user can't screw around with the internals, but the function will be sitting there as part of the interface when the user should have nothing to do with it. If I use the friend approach then the internals are never exposed to the user, but they are to the Graphics class. It does however, tightly couple the two classes. I'm currently using the friend approach, and it hasn't been too messy. AFAIK, this sort of situation is the reason for friends in the first place, but I'm not sure if having 3 or 4 friends in a class is considered abuse or not. I'd consider the listed classes to be logically directly related to the Graphics class, and for the moment at least, I don't foresee the adding of more classes with the same situation to couple with the Graphics class. Any thoughts? Is this a legitimate and necessary use of friends?
Advertisement
I think that because you are indeed tightly coupling the class together and as you said you are removing the getter from the interface then friend seems viable.

However, i see no harm in exposing the internal to the user if they cant modify it and therefore you could take away the overuse of friends by having the getter.

Having friend in use this much indicates to me that you have a design problem.

I would go with the getter.

Hope that helps,

Dave
I'd prefer:

ImageHandle (filename?)FontHandle (filename and size?)Graphics (class used by the user)Direct3D::Image (exposes Direct3D details, only used by Direct3D::* classes, no parent class)Direct3D::Font (same as Image)Direct3D::Graphics (implementation of Graphics, uses Direct3D::Image to render ImageHandles, etc)


Thus, the Direct3D implementation (which is by necessity fairly tightly coupled, at least to DirectX) becomes more seperated from the user code.

[Edited by - MaulingMonkey on April 23, 2006 2:14:08 PM]

This topic is closed to new replies.

Advertisement