Подтвердить что ты не робот

Определение строковых констант класса в С++?

Я видел код с этими двумя стилями, я не уверен, что он лучше другого (это только вопрос стиля)? Есть ли у вас какие-либо рекомендации относительно того, почему вы выбрали один за другим.

 //Example1
 class Test {

    private:
        static const char* const str;

};

const char* const Test::str = "mystr";

//Example2
class Test {

     private:
         static const std::string str;

};

const std::string Test::str ="mystr";
4b9b3361

Ответ 1

Обычно вы предпочитаете std::string поверх простых указателей char. Однако здесь указатель char, инициализированный строковым литералом, имеет существенное преимущество.

Существует две инициализации для статических данных. Один называется статической инициализацией, а другой называется динамической инициализацией. Для тех объектов, которые инициализируются постоянными выражениями и являются POD (например, указатели), С++ требует, чтобы их инициализация происходила в самом начале, до того, как произойдет динамическая инициализация. Инициализация такого std::string будет выполнена динамически.

Если у вас есть объект класса, являющийся статическим объектом в каком-либо файле, и ему нужно получить доступ к строке во время ее инициализации, вы можете полагаться на ее настройку уже при использовании версии const char* const при использовании версии std::string, которая не инициализирована статически, вы не знаете, инициализирована ли строка, потому что порядок инициализации объектов на границах единицы перевода не определен.

Ответ 2

Hmmm, a std::string не совпадает с константой char *. Я обычно ошибаюсь на стороне использования std::string, потому что это класс, который имеет много дополнительных возможностей, которые делают его намного проще в использовании.

Если производительность имеет первостепенное значение, и вы используете const char * для эффективности, идите таким образом.

Ответ 3

Я стараюсь использовать std::string над char * при выполнении С++. Я предпочитаю std::string в основном за свои встроенные возможности, а также удобство и безопасность, не имея необходимости иметь дело с указателями.

Однако, как отмечали другие, версия const char * может быть благоприятной, если вы чрезмерно обеспокоены производительностью. Я, кажется, помню, что кто-то умный однажды заявил, что преждевременная оптимизация - это корень всех злых (или некоторых таких).:)

Ответ 4

Первый пример требует меньших накладных расходов для управления строкой (т.е. просто указателем на раздел ТЕКСТ). Кроме того, для второго метода может потребоваться распределение кучи, а также для копирования литерала строки в буфер std: string. Итак, вы получите две копии данных.

Ответ 5

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

Ответ 6

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

Ответ 7

Прежде всего, если бы не использовать char *. Если вы хотите строку ASCIIZ, определите одну из них напрямую:

const char Test::str[] = "mystr";

По большей части это то, что я буду использовать. Зачем тратить время и память на накладные расходы класса string.

Обратите внимание, что "sizeof (Test:: str)" точно даст вам длину массива, которая является длиной строки, включая завершающий NUL (strlen (str) +1).