Constants and #defines are both very useful if used appropriately and very destructive if used inappropriately. The same goes for everything in C++
The trick is to pick a style that suits you and your project (unless there are specific design constraints or well known "best practice" ways of doing a particular thing).
With regard to teamwork on projects...
If you are looking at collaborative working on a game one of the most useful things you can do is get some sort of source control set up. Personally I recommend either CVS (http://www.nongnu.org/cvs/) or Subversion (http://subversion.tigris.org/). Both of which will allow you to keep tabs on who changed what in the code base and offer the ability to roll back changes if something/someone breaks the build.
They also provide basic mechanisms for resolving conflict (what happens if two people make different changes to the same file) which can be a godsend when working in a team.
Combined with a tool like winmerge (http://winmerge.org/) this type of source control is very useful.
From a more organisational point of view to get effective collaborative working you need to break down the project into clearly defined areas of responsibility. That way you know precisely who is working on net code and who is doing the GUI etc.
Perhaps the hardest thing with working in a team and one of the reasons things fail early tends to be getting everybody to agree to what the project actually is up front and what level of input they will get into its core design once it is set rolling.
When working with others especially on something as creative as games development it is essential to have a good (and as far as possible) complete design document. That way once everybody has signed up to it and agreed what they are all trying to create there are few arguments to be had.
Ideally the design document (or another document) should also specify coding standards etc. Things are a lot easier if everybody uses the same style of coding in a project. It can get confusing if one coder is using all lowercase for constants and one is using uppercase for example.
Having the projects goals clearly documented also helps to put a lid on feature creep. One person can add dangerous complexity to a project by thinking "Its cool as it is but if I add this then it will rule..." (I know, I am as guilty of this as anybody) and the more people working on something the more (normally very good) ideas will get injected which although valuable and a positive part of working in a team can lead to vapour-ware if not managed correctly.
You can also make things a lot easier on you and your team if you ensure that you design in modularity from the outset. People should be looking at delivering encapsulated classes and functions with clearly defined interfaces rather than snippets or large monolithic blocks of code. Keeping delivery to functions and classes makes things easier to test, easier to document and also means that if you loose a member of the team for whatever reason their code should be small and atomic enough to understand and continue to work with. This can help to avoid potential show-stoppers in the future.
I hope some of this is useful
Macro