статические строковые константы в классе vs namespace для констант [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 риск динамического выделения памяти для строкового литерала, который будет оставаться постоянным в течение всего срока службы программы (и двоичного файла), поэтому их следует избегать.

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, но более беспорядочным образом.

Если вы собираетесь использовать класс, который имеет только статические члены, особенно для глобального доступа / констант, используйте пространство имен.