Практически все что было сказано выше в этой ветке верно. От себя хочу добавить пример который иллюстрирует преимущество констант перед define'ами.
Представьте себе что вы имеете #define MY_ID 123. Если при написании кода вы допустили ошибку связанную с MY_ID, и при компиляции вы получите ошибку компилятора, то имени MY_ID в описании этой ошибки не будет. Связано это с тем, что еще до компилятора препроцессор заменил MY_ID на 123. И поэтому в сообщении об ошибке будет фигурировать именно 123. А если define в код ввели не вы, а кто-то другой, то на отлов ошибки уйдет масса времени.
И прочитайте кстати правило номер 1 из книги Скота Майерса "Эффективное использование С++, 50 рекомендаций".