C ++ лучший способ определить константы между файлами - PullRequest
10 голосов
/ 13 марта 2009

Я работаю над игрой и у меня интересный вопрос. У меня есть некоторые постоянные значения для всей игры, которые я хочу реализовать в одном файле. Прямо сейчас у меня есть что-то вроде этого:

constants.cpp

extern const int BEGINNING_HEALTH = 10;
extern const int BEGINNING_MANA = 5;

constants.hpp

extern const int BEGINNING_HEALTH;
extern const int BEGINNING_MANA;

А потом файлы просто #include "constants.hpp" Это прекрасно работало, пока мне не понадобилось использовать одну из констант в качестве параметра шаблона, потому что внешние константы не являются допустимыми параметрами шаблона. Итак, мой вопрос, каков наилучший способ реализации этих констант? Я боюсь, что простое помещение констант в заголовочный файл приведет к их определению в каждой единице перевода. И я не хочу использовать макросы.

Спасибо

Ответы [ 8 ]

19 голосов
/ 13 марта 2009

Избавьтесь от extern и все готово.

Этот код прекрасно работает в заголовке, потому что все является "действительно постоянным" и поэтому имеет внутреннюю связь:

const int BEGINNING_HEALTH = 10;
const int BEGINNING_MANA = 5;
const char BEGINNING_NAME[] = "Fred";
const char *const BEGINNING_NAME2 = "Barney";

Этот код нельзя безопасно поместить в заголовочный файл, поскольку каждая строка имеет внешнюю связь (либо явно, либо из-за того, что она не является действительно постоянной):

extern const int BEGINNING_HEALTH = 10;
extern const int BEGINNING_MANA = 5;
const char *BEGINNING_NAME = "Wilma";  // the characters are const, but the pointer isn't
10 голосов
/ 13 марта 2009

Как насчет перечислений?

constants.hpp

  enum {
    BEGINNING_HEALTH = 10,
    BEGINNING_MANA = 5
  }
6 голосов
/ 13 марта 2009

Используйте «static const int» в вашем файле .hpp и ничего не помещайте в файл .cpp (кроме любого другого кода, который у вас там есть).

3 голосов
/ 13 марта 2009

использовать пространства имен:

namespace GameBeginning {
    const int HEALTH = 10;
    const int MANA   = 5; 
};

тогда вы можете использовать в качестве player.health = GameBeginning :: HEALTH;

0 голосов
/ 13 марта 2009

Что случилось с простым:

#define BEGINNING_HEALTH 10

Человек, это были дни.
Ой, подождите, эти все еще дни!

0 голосов
/ 13 марта 2009

В качестве быстрого ответа на заглавный вопрос, одноэлементный шаблон - это лучший, C ++ способ определить константы между файлами и обеспечить только один экземпляр объекта.

Что касается проблемы с параметром шаблона, вам нужно передать тип, а не значение. Ваш тип "int".

0 голосов
/ 13 марта 2009

Большинство компиляторов просто не выделяют место для постоянных значений POD. Они оптимизируют их и относятся к ним, как будто они были #define d, не так ли?

0 голосов
/ 13 марта 2009

возможно что-то вроде статического класса?

class CONSTANTS {
public:
static inline int getMana() { return 10;};
};
...