Статические строковые константы в классе vs пространство имен для констант [C++]
Я хочу объявить строковые константы, которые будут использоваться в различных классах проекта. Я рассматриваю две альтернативы
Опция 1:
#header file
class constants{
static const string const1;
};
#cpp file
const string constants::const1="blah";
Вариант 2:
#header file
namespace constants{
static const string const1="blah";
};
Просто интересно, что будет лучшей реализацией.
Уже посмотрел на
Где хранить именованные константы класса в C++
Где поместить константные строки в C++: статические члены класса или анонимные пространства имен
ОБНОВИТЬ:
Вариант 3:
Основываясь на предложениях "potatoswatter" и "sellibitze", у меня в настоящее время есть следующая реализация?
#header file
namespace constants{
extern const string& const1(); //WORKS WITHOUT THE EXTERN ***WHY***
};
#cpp file
namespace constants{
const string& const1(){static string* str = new string ("blah"); return *str;}
}
Я включаю заголовочный файл, где мне нужно использовать константы. Существуют ли основные недостатки этой реализации?
4 ответа
Обновление через 2 года:
Каждый глобальный доступ к более чем одному исходному файлу должен быть заключен в inline
Функция так, что компоновщик разделяет объект между файлами, и программа инициализирует его должным образом.
inline std::string const &const1() {
static std::string ret = "hello, world!";
return ret;
}
inline
функция неявно extern
и может быть обернут в именованное пространство имен или класс, если хотите. (Но не используйте класс только для хранения статических членов, так как для этого лучше использовать пространства имен. И не используйте анонимное пространство имен, так как это повредит компоновщику, и каждый источник увидит по-своему std::string
объект.)
Все ответы, которые прибегают к std::string
риск динамического выделения памяти для строкового литерала, который будет оставаться постоянным на протяжении всего жизненного цикла программы (и двоичного кода), поэтому их следует избегать.
Ответ Sellibitze близок, но у него есть проблема, чтобы объявить его один раз, а затем определить его в другом месте, что я не нахожу элегантным, и это больше работы. Лучший способ будет
namespace constants {
const char * const blah = "blah!"
const char * const yada = "yada yada!"
}
Это решение обсуждается здесь далее.
Ни. Я бы пошел с этим:
// header file
namespace constants {
extern const char const1[];
}
// cpp file
namespace constants {
extern const char const1[] = "blah";
}
Заголовочный файл содержит объявление const1
с неполным типом, но конвертируемым в char const*
и cpp-файл содержит определение массива символов с внешней связью. Там нет динамической инициализации, как у вас с std::string
, Так что это плюс, ИМХО.
Вариант 1 достигает того же, что и Вариант 2, но более сложным способом.
Если вы собираетесь использовать класс, который имеет статические члены, особенно для глобального доступа / констант, используйте пространство имен.