Статические строковые константы в пространстве классов 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. Итак, что плюс, ИМХО.