Sign in to follow this  
DesignerX

A C++ programming issue

Recommended Posts

I read an article from this site about game programming which is called "Code on the Cob - by Chris Hargrove" On the fifth section called "From Top to Bottom" a very important issue was raised about class use. The author explains that by using a class , both its public and private variables are exposed (not by manipulation, just by knowing whats in the class) and the bigger problem is that if for some reason (which will probably always occur) I find the need to change one of the private variables , it will require recompilation of all file using the class (by including its header file). And on a big project this will cost alot of recompilations (=time). So that why he uses static variables which he declares in a .cpp file (and not in a .h file). And thus prevents the problem mentiond above. Now I think this is a very good point but I'm a class freak. I think that the use of classes makes projects more readable and understandable and most importantly modifiable. What do you think about it, should I move to using static variables (a C-style approach that I don't much promote using) or there is a way for avoiding this problem ???

Share this post


Link to post
Share on other sites
I think it sounds silly to make design/implementation decisions based on compilation time.

Share this post


Link to post
Share on other sites
If this is a major concern for you, I would highly recommend using the pimpl idiom, Described here in GotW here and here, and on our very own GameDev here.

Not only does it sovle the issue you describe, but also provides a meachanism for separating the interface and implementation.

Phil

Share this post


Link to post
Share on other sites
Interfaces *might* work, as you can fiddle with the class without effecting the interface. Seems like a lot of trouble to go to though.

Another option would be

struct ALLMYVARS4CLASSA
{
int stuff1,stuff2,etc;
};

class A
{
ALLMYVARS4CLASSA * pData;
//functions here
};

Now as you only have a pointer in the class you might be able to fiddle with the struct veribales as much as you like without it recompiling dependancies.
!Might!


Share this post


Link to post
Share on other sites
I agree sometimes it is useful to hide the (private) implementations from a class from the users of the class. Take a SoundManager, for example, that privately uses all kinds of sound-related stuff, whose definitions should also be included etc. etc..
What I do in these cases is create a interface class (in our example ISoundManager) containing only pure virtual methods and one static factory method. A actual SoundManager class then inherits from ISoundManager, defining all the private goodies. Now you can include ISoundManager.h in all your classes without recompilation if you change the private stuff...

EDIT: Hmmzz.. I type too slow :-)

Share this post


Link to post
Share on other sites
Quote:
Original post by DesignerX
I read an article from this site about game programming which is called
"Code on the Cob - by Chris Hargrove"

On the fifth section called "From Top to Bottom" a very important issue was raised about class use.


Although I haven't read the other articles I personally believe that the advice given in that particular chapter is way off base. I'm not sure which one is worse. Associating design to implementation details or that if you use a top-down approach to designing a game engine reuse will be crippled.

As far as I am concerned the issue of data exposure presented in the article is irrelevant in C++. The unwavering insistence of absolute data hiding is generally fueled by developers having a hard time letting go of the habits and practices they acquired programming in C. Choosing to remove or hide data when declaring classes with the intent of preventing other programmers from accessing it through some nefarious act is an utter waste of time. Any adverse side effect caused by accessing data declared as private or protected is a) being done explicitly and b) is just plain stupid to do. Why waste the time doing this to prevent something that is very unlikely to happen?

This issue is addressed (much better btw) by existing design patterns such as interfaces, composites, bridges, adapters, etc. These patterns are well defined, incredibly effective, and mature.

Links:

Composite Pattern
Bridge Pattern
Adapter Pattern
Interface Pattern

If you do find a situation where a pure interface provides the desired result there are several things that can be done:

1) Declare a class where all methods (except the constructor) are pure virtuals and public.
2) Add a static method responsible for creating an object of this type.
3) If you are disallowing developers from inheriting from this class declare the constructor as private and declare the implementation class as a friend. You can use a forward declaration to the implementation to eliminate the need to include it's header file friend class Implementation;).
4) If you are allowing developers to inherit from this class declare the constructor as protected. This ensures that the class can not be instantiated in the event you change all methods from pure virtual and provide a base implementation. This of course switches it from an interface to a class (conceptually anyway) but it has been known to happen.

class Interface {
private:
friend class Implementation;

Interface() {};
public:
virtual ~Interface() {};
virtual void OnStopCommand() = 0;
virtual void OnGoCommand() = 0;
virtual void OnBeLazyCommand() = 0;

// Creation point
static Interface *Create();
};



class Implementation : public Interface {
public:
Implementation() { }
virtual ~Implementation() { }
virtual void OnStopCommand() { }
virtual void OnGoCommand() { }
virtual void OnBeLazyCommand() { }
};


Interface *Interface::Create() {
return new Implementation();
}

Share this post


Link to post
Share on other sites
From what you've posted, I don't believe that the author presents a very compelling argument. If you find yourself changing something from public to private very often, then you are probably not doing enough design work beforehand.

In reality, big projects are totally rebuilt overnight on a dedicated build machine so it doesn't matter. They're also typically broken up into seperate DLLs etc, and most classes are not shared amoung that many source files anyway.
I should know, I'm working on a big real-world project.

Share this post


Link to post
Share on other sites
Quote:
Original post by iMalc
From what you've posted, I don't believe that the author presents a very compelling argument. If you find yourself changing something from public to private very often, then you are probably not doing enough design work beforehand.

In reality, big projects are totally rebuilt overnight on a dedicated build machine so it doesn't matter. They're also typically broken up into seperate DLLs etc, and most classes are not shared amoung that many source files anyway.
I should know, I'm working on a big real-world project.


I agree with you, a good design will prevent such things to happen oftenly, but there will always be something that need to be changed or improved.
So what do you suggest, should I continue using classes as they are (my preffered way) or should I start messing with desgin patterns for hiding implementation dependencies for less recompliations (which requires alot of work for all the classes I wrote, and for my opinion makes the code less readable and easier to write)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this