статические строковые константы в классе vs пространство имен для констант [c ++] - PullRequest
17 голосов
/ 08 сентября 2010

Я хочу объявить строковые константы, которые будут использоваться в различных классах проекта.Я рассматриваю две альтернативы

Вариант 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 ]

11 голосов
/ 08 сентября 2010

Обновление 2 года спустя:

Каждый глобальный объект, доступный более чем одному исходному файлу, должен быть заключен в функцию inline, чтобы компоновщик разделял объект между файлами, иПрограмма инициализирует его правильно.

inline std::string const &const1() {
    static std::string ret = "hello, world!";
    return ret;
}

Функция inline неявно extern и может быть обернута в именованное пространство имен или класс, если хотите.(Но не используйте класс только для хранения статических членов, так как для этого лучше использовать пространства имен. И не используйте анонимное пространство имен, так как это повредит компоновщику, и каждый источник увидит свой объект std::string.)

7 голосов
/ 29 июля 2013

Все ответы, которые обращаются к std::string, создают риск динамического выделения памяти для строкового литерала, который будет оставаться постоянным в течение всего времени жизни программы (и двоичного файла), поэтому их следует избегать.

sellibitze ответ близок, но у него есть проблема, чтобы объявить его один раз, а затем определить его в другом месте, что я не нахожу элегантным, и это больше работы. Лучший способ будет

namespace constants {
    const char * const blah = "blah!"
    const char * const yada = "yada yada!"
}

Это решение обсуждается далее здесь .

5 голосов
/ 09 сентября 2010

Ни.Я бы сказал следующее:

// header file
namespace constants {
extern const char const1[];
}

// cpp file
namespace constants {
extern const char const1[] = "blah";
}

Заголовочный файл содержит объявление const1 с неполным типом, но конвертируемым в char const*, а файл cpp содержит определение массива символов с внешней связью,Там нет динамической инициализации, как у вас с std::string.Так что это плюс, ИМХО.

4 голосов
/ 08 сентября 2010

Вариант 1 достигает того же, что и Вариант 2, но более грязным способом.

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

...