We usually use IClassName for interfaces (pure abstract classes).
Yep, we do that too. I forgot to put interfaces in there.
Second, don't calculate anything in the main program. Have all calculations done with functions. Also, make sure each function is short and don't calculate more than one thing in each. Splitting up the functions like this helps organize the program as you go along, but the most beneficial part of this is that it allows very easy modification of the program. Need to add a few features? Just adjust a few functions to call out additional functions that your new features will use. It also makes sure you understand the interrelationships between the functions, so changing one thing won't adversely affect other things in your program.
I totally agree. I touched on this a bit with the one about functions.
Also, The C Programming Language (Ansi C) by Kenigan and Ritchie is one of the best reference books to have around. It is a very good book for anyone in the industry. (Even if you aren't just a beginner)
I think that was the book I learned C from in college.
Oh, yeah, that's a good one. We use CTRL+F8 a lot.
P.S. I'm really bad at #7. Is there any good tricks to avoid re-inventing the wheel? Its really a waste of my time to try to code something that already exists, and I can't seem to find.
The STL and boost both have a lot of useful algorithms and classes to help with stuff. CodeProject often has really good stuff too. That's where we foung PUGXML and a helper class for threads that's come in really useful. Other than that, Google it. For game related programming resources, Gamasutra has a list on it site and you can also ask at gamedev.net. I also meant code that exists in our engine already, though, so in that case it's simply a matter of checking with another developer before writing another xml parser or whatever.
Any chance of getting Stardock guidelines for data architecture?
We store data in classes whose data members are private or protected and accessible only by functions (we try to avoid using friends). Rather than trying to make the class generic, we actually have specfic varaibles for specific members. We had a programmer on GalCiv2 who introduced us to the concept of property buckets, which map a string ID to another string which holds the value of the field. While this is useful for temporary storage while reading in for XML, using it for regular classes makes it much harder to debug and adds overhead. So rather than having a std::map<std::string, std::string> to hold all of the class' data members, we actually declare them normally, like FLOAT m_fStrength, FLOAT m_fSensorRange, etc. The most generic we get is to have an array of abilities, where the index of the array is defined in an enum. That way, it's quick and easy to add new abilities but we can still easily view the values in the debugger. Other than that, I'd have to think about what we do more.
Don't use magic numbers: significant values should not be typed inline, but rather defined somewhere obvious.
Heh, I should have thought of this one. I complain about it all the time.
For instance the much abused Hungarian notation, works fine as long as you don't change your type.
Yes, but why are you changing the type? Changing type should not be done lightly. Things like population, which cannot be negative, should be expressed as ULONGs. Changing it to LONG would be meaningless, and changing it to a FLOAT or DOUBLE would be equally silly. If you're making a switch from unsigned to signed, you're going to have to make a lot of changes and make certain that everywhere that deals with that variable is still using correct behavior.
18) Does that mean you don't have a compilation server compiling all the check ins in real time? Why would you test compilation AFTER committing?
Everyone is expected to check in code that compiles. But if they forget to check in a file, that will make someone else's code not compile when they update, and if they've gone home for the day already, that's an issue. CVS ignores any files that haven't been added to the project, unlike other version control, which is why that can happen.
I was surprised to see the comment about std::for_each() being faster than writing a for() loop yourself. Unless c++ compilers have changed in recent history, the best you can hope for is that the compiler will inline the for loop and also the functor call and you will end up with code that is as fast as a for() loop. More likely your functor code will be too complex to be inlined and you will end up with slightly slower code (an extra function call each iteration).
I had been certain that this was in Effective STL, but maybe I was thinking of the std::find function. Now I'm going to have to re-read Effective STL.