Мне больше define нравится, почему его нежелательно использовать?
define исторически остался от C. Сейчас рекомендуется вместо него использовать enum и const.
#define это макрос, т.е. все что идет за ним просто подставляется в текст программы место его имени.
С этим могут быть проблемы:
C++ (Qt)
#defien NUM 10 + 10
int val = NUM * 2;
эта конструкция развернеться в:
C++ (Qt)
int val = 10 + 10 * 2;
Соответственно результат будет не 40, как хотелось бы, а 30.
С константой такое произойти не может.
#define A 10.123
Константа расположена в одном месте, макрос же будет подставлять это число там где будет прописано имя макроса. Для чисел с плавающей точкой это меннее эффективно.
Также для строк. Если макрос будет использован в нескольких файлах, копия этой строки будет в каждой объектной единице (хотя компилятор сможет это оптимизировать, но это будет заслуга компилятора).
Нет проверки типов на этапе компиляции. У константы задается тип, который компилятор сможет проверить, у макроса его нет.
Макрос не принадлежит пространствам имен.
Сейчас не вспомню все проблемы, но они есть.