Куда я помещаю постоянные строки в C ++: статические члены класса или анонимные пространства имен? - PullRequest
26 голосов
/ 17 марта 2010

Мне нужно определить несколько константных строк, которые будут использоваться только одним классом. Похоже, у меня есть три варианта:

  1. Вставьте строки непосредственно в места, где они используются.

  2. Определите их как частные статические постоянные члены класса:

    //A.h  
    class A {  
    private:  
       static const std::string f1;  
       static const std::string f2;  
       static const std::string f3;  
    };  
    
    //A.cpp  
    const std::string f1 = "filename1";  
    const std::string f2 = "filename2";  
    const std::string f3 = "filename3";  
    
    //strings are used in this file  
    
  3. Определите их в анонимном пространстве имен в файле cpp:

    //A.cpp  
    namespace {  
      const std::string f1 = "filename1";  
      const std::string f2 = "filename2";  
      const std::string f3 = "filename3";  
    }  
    
    //strings are used in this file  
    

Учитывая эти параметры, какой из них вы бы порекомендовали и почему? Спасибо.

Ответы [ 9 ]

21 голосов
/ 17 марта 2010

Я бы поместил их в анонимное пространство имен в файле CPP. Это делает их приватными для реализации и в то же время делает их видимыми для не-членских функций, которые являются частью реализации (таких как operator<<).

5 голосов
/ 17 марта 2010

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

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

Если они используются в нескольких местах в cpp, я бы выбрал анонимное пространство имен.

Другой вариант, который вы не упоминаете, - это определить их как статические переменные внутри cpp. это несколько эквивалентно опции анонимного пространства имен и более похоже на C, чем C ++.

3 голосов
/ 17 марта 2010

Статические члены класса.

Если они используются в нескольких местах одним классом, обычно легче поддерживать порядок вещей - и позже найти, где вы все определили - если вы оставите их определенными в классе, который их использует. Определение их на месте затрудняет их поиск и последующее изменение. И я бы выбрал конкретный класс для анонимного пространства имен для более чистого определения и использования класса.

2 голосов
/ 17 марта 2010

Если используется только в файле класса .cpp, нет необходимости использовать какое-либо пространство имен, просто скажите:

const std::string f1 = "filename1";  
const std::string f2 = "filename2";  
const std::string f3 = "filename3";  

Чрезмерное использование пространств имен, кажется, является новой вещью - я лично не вижу привлекательности.

2 голосов
/ 17 марта 2010

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

0 голосов
/ 18 октября 2012

Просто поместите строки const в область действия файла в файле реализации, анонимное пространство имен не обязательно ограничивать их использование только этим классом.

C ++ 003 Standard C.1.2 Предложение3: основные понятия

Change: A name of file scope that is explicitly declared const, and not explicitly declared extern, has internal linkage, while in C it would have external linkage

Примечание. Анонимное пространство имен помогает уменьшить конфликты имен.

0 голосов
/ 18 марта 2010

Как бы вы ни делали, нужно быть осторожным с одной вещью: я бы не рекомендовал использовать статические объекты std :: string, вместо этого используйте static char *. Причина этого связана с потенциальными проблемами с порядком инициализации. Допустим, у вас есть статический экземпляр класса, конструктор которого ссылается на строку A::f1. Нет никакой гарантии, что A::f1 был построен, и вы получите сбой, или, что еще хуже, не сбой, а поддельные данные.

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

0 голосов
/ 17 марта 2010

Я думаю, что реальная проблема заключается в следующем: действительно ли строки используются только внутренне при реализации класса, или они используются где-то еще.

Чтобы быть по-настоящему придирчивым, я бы постарался сохранить интерфейс класса настолько чистым, насколько это возможно, чтобы строки имени файла не интересовали «внешний» мир. Я бы скрыл их внутри только в .cpp-файле. И в этом случае я не думаю, что буду беспокоиться о пространстве имен, а просто сохраню «статичность» (т. Е. Внутри .cpp-файла).

0 голосов
/ 17 марта 2010

Из трех вариантов, единственный, который вы должны избегать, это # ​​1. Не используйте магические куки в вашем коде. Поместив константы в пространство имен или в класс, вы упростите расширение и поддержку своего кода в будущем.

Если ваши константы имеют глобальный характер, то между 2 и 3 это мало что значит. Важно то, что вы выбираете один и придерживаетесь его. Но если у вас есть константы, которые применяются к определенному классу, то они должны быть частью этого класса.

Лично я бы использовал пространство имен для большинства вещей.

...