Статические строковые константы в пространстве классов vs для констант [С++]
Я хочу объявить строковые константы, которые будут использоваться для разных классов в проекте. Я рассматриваю две альтернативы
Вариант 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";
};
Просто интересно, что было бы лучше.
Уже посмотрел
Где хранить определенные именованные константы класса в С++
Где помещать постоянные строки в С++: статические члены класса или анонимные пространства имен
UPDATE:
Вариант 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;}
}
Я включаю заголовочный файл, где мне нужно использовать константы. Существуют ли какие-либо серьезные недостатки этой реализации?
Ответы
Ответ 1
Обновление через 2 года:
Каждый глобальный доступ, доступный более чем одним исходным файлом, должен быть обернут в функцию inline
, чтобы компоновщик совместно использовал объект между файлами, и программа инициализирует его правильно.
inline std::string const &const1 {
static std::string ret = "hello, world!";
return ret;
}
Функция inline
неявно extern
и может быть обернута в именованное пространство имен или класс, если хотите. (Но не используйте класс только для того, чтобы содержать статические члены, поскольку пространства имён лучше для этого. И не используйте анонимное пространство имен, так как это победит компоновщик, и каждый источник увидит другой объект std::string
.)
Ответ 2
Все ответы, прибегающие к std::string
, запускают риск динамического выделения памяти для строкового литерала, который будет оставаться постоянным на протяжении всего жизненного цикла программы (и двоичного), поэтому их следует избегать.
sellibitze ответ приходит, но у него есть проблема объявить его один раз, а затем определить его в другом месте, что я не считаю элегантным и больше работаю. Лучший способ -
namespace constants {
const char * const blah = "blah!"
const char * const yada = "yada yada!"
}
Это решение обсуждается далее здесь.
Ответ 3
Вариант 1 достигает того же, что и Option 2, но более беспорядочным способом.
Если вы собираетесь использовать класс, в котором есть только статические элементы, особенно для глобального доступа/констант, используйте пространство имен.
Ответ 4
Ни. Я бы пошел с этим:
// header file
namespace constants {
extern const char const1[];
}
// cpp file
namespace constants {
extern const char const1[] = "blah";
}
В заголовочном файле содержится объявление const1
с неполным типом, но конвертируемое в char const*
, а файл cpp содержит определение массива символов с внешней связью. Нет динамической инициализации, как у вас с std::string
. Итак, что плюс, ИМХО.