Google C++ Style Guide / Google C++ Style Guide: Scoping
| Английский оригинал | Перевод на русский | |
|---|---|---|
Сожалеем, но текст оригинала доступен только зарегистрированным пользователям. |
Области видимости flyngate 12.10.13 в 23:12 |
|
|
Пространства имен xmorph 14.03.13 в 09:59 |
||
|
безымянные пространства имен поддерживаются в файлах .сс . С именными пространствами имен, выберите название, основанное на проекте, и, желательно, его путь. Не используйте using-директиву. Nuriya94 27.03.13 в 16:40 безымянные пространства имен поддерживаются в файлах .сс . Для имен лучше выбирать название, основанное на проекте, и, желательно, его путь. Не используйте директиву using. aereiae 05.02.14 в 00:11 |
||
|
Определение: xmorph 14.03.13 в 10:01 |
||
|
Пространства имен подразделяют глобальную область действия на отдельные, называемые областями действия, и они полезны для предотвращения именного конфликта в глобальной области. Nuriya94 27.03.13 в 16:50 |
||
|
Плюсы: xmorph 14.03.13 в 10:01 |
||
|
Пространства имен предоставляют (иерархическую) ось присваивания имен, кроме (также иерархической) оси, предоставляемой классами. Nuriya94 27.03.13 в 16:52 |
||
|
Например, если два разных проекта имеют класс Foo в глобальной области, эти символы могут конфликтовать во время компиляции либо во время исполнения программы. Если каждый проект расположит их код в пространстве имен, то проект1::Foo и проект2::Foo теперь являются отдельными символами, которые не конфликтуют. Nuriya94 27.03.13 в 16:57 |
||
|
Минусы: xmorph 14.03.13 в 10:01 |
||
|
Пространства имен могут запутаться, потому что они предоставляют дополнительную (иерархическую) ось именования, в дополнение к оси именования, предоставляемой классами. Nuriya94 27.03.13 в 16:58 |
||
|
Использование безымянных пространств имен в файлах заголовков могут легко нарушить правило одного описания (ODR) Nuriya94 27.03.13 в 17:00 |
||
|
Вывод: xmorph 14.03.13 в 10:02 |
||
|
Используйте пространства имен в соответствии с методикой, описанной ниже. Завершайте пространства имен комментариями, которые показаны в примерах. Nuriya94 27.03.13 в 17:03 |
||
|
Безымянные пространства имен Nuriya94 27.03.13 в 17:03 |
||
|
Безымянные пространства имен допустимы и даже поддерживаются в файлах .сс чтобы избежать именные конфликты во время исполнения: Nuriya94 27.03.13 в 17:04 |
||
|
Однако, описания области действия файлов, которые связаны с индивидуальными классами, могут быть объявлены в этих классах как типы, статические переменные-члены класса или статические функции-члены класса скорее чем в качестве членов безымянных пространств имен. Nuriya94 27.03.13 в 17:08 |
||
|
Не используйте безымянные пространства имен в файлах .h Nuriya94 27.03.13 в 17:09 |
||
|
Именные пространства имен Nuriya94 27.03.13 в 17:09 |
||
|
Именные пространства имен должны быть использованы следующим образом: Nuriya94 27.03.13 в 17:10 |
||
|
Пространства имен охватывают весь исходный файл после включений, определений/объявлений флажков, и отправляют объявления классов из остальных пространств имен: Nuriya94 28.03.13 в 14:25 |
||
|
Не объявляйте ничего в namespace std, даже не посылайте объявления стандартной библиотеки классов. Объявляемые модули в namespace std - неопределенные характеристики, то есть недоступны. Чтобы объявить модули из стандартной библиотеки, включите соответствующий файл заголовка. Nuriya94 28.03.13 в 13:54 |
||
|
Вы можете не использовать using-директиву чтобы сделать все имена из пространства имен доступными. Nuriya94 28.03.13 в 13:55 |
||
|
Вы можете использовать using-объявление где угодно в файле .сс и в функциях, методах или классах в файлах .h Nuriya94 28.03.13 в 13:55 |
||
|
Псевдонимы пространства имен допустимы везде в файлах .сс, везде внутри именного пространства имен, охватывающего весь файл .h, функции и методы. Nuriya94 28.03.13 в 14:00 |
||
|
Отметьте, что псевдоним в .h файле видим всем файлам, которые его включают, так публичные заголовки (доступные вне проекта) и заголовки, транзитивно включенные ими, должны избегать определения псевдонима для выполнения главной цели – сохранить API ограниченным, насколько это возможно. Draks 17.05.13 в 13:27 |
||
|
Вложенные классы Andersen1313 01.04.13 в 16:46 |
||
|
Не смотря на то, что Вы можете использовать публичные вложенные классы, когда они являются частью интерфейса, полагают, что пространство имен не допускает их объявления в глобальной области видимости. Draks 17.05.13 в 13:28 |
||
|
Определение: Andersen1313 01.04.13 в 16:46 |
||
|
Класс может определять другой класс внутри себя; этот класс так же будет называться членом класса. Andersen1313 01.04.13 в 16:48 |
||
|
Доводы "за": Andersen1313 01.04.13 в 16:48 Плюсы: aereiae 05.02.14 в 00:34 |
||
|
Это полезно когда внутренний (или член) класс используется только в охватывающем классе; создание этого члена вводит его в область видимости охватывающего класса, что не загрязняет окружающую область видимости именем класса. Вложенные классы могут иметь дальнее определение внутри охватывающего класса и потом быть определенными в .cc файле, избегая включения определения вложенного класса в определении охватывающего класса, т.к. вложенное определение класса, как правило, относится только к реализации. Andersen1313 01.04.13 в 16:59 |
||
|
Доводы "против": Andersen1313 01.04.13 в 16:59 Минусы: aereiae 05.02.14 в 00:34 |
||
|
Вложенные классы могут быть предварительно объявлены только внутри определения охватывающего класса. Таким образом, любой заголовочный файл, использующий указатель Foo::Bar* должен включать полное объявление класса Foo. Draks 17.05.13 в 13:18 |
||
|
Заключение: Andersen1313 02.04.13 в 03:56 |
||
|
Не делайте вложенные классы открытыми (спецификатор доступа public), пока они являются частью интерфейса, например, класс который содержит набор опций для некоторого метода. Andersen1313 02.04.13 в 03:58 |
||
|
Неклассовые и статичные поля и глобальные функции. aereiae 05.02.14 в 01:15 |
||
|
Предпочитайте функции, не являющиеся членами класса и расположенные в пространстве имен, или статические члены функции глобальным функциям; редко используйте абсолютно глобальные функции. Draks 17.05.13 в 13:18 |
||
|
Плюсы: Draks 17.05.13 в 13:26 |
||
|
Не являющиеся членами и статические члены функции могут быть полезными в некоторых ситуациях. Помещение функций, не являющимися членами класса, в пространство имен позволяет избежать загрязнения глобального пространства имен. Draks 17.05.13 в 13:24 |
||
|
Минусы: Draks 17.05.13 в 13:26 |
||
|
Функции, не являющиеся членом, и статические члены функции могут иметь больше смысла как члены нового класса, особенно если они получают доступ к внешним ресурсам или имеют существенные зависимости. Draks 17.05.13 в 13:37 |
||
|
Решение: lyzov 17.08.13 в 16:30 |
||
|
Иногда полезно, или даже необходимо, определить функцию, не связанную с экземпляром класса. Такая функция может быть или статическим членом или функцией, не являющейся членом. Функции, не являющиеся членом, не должны зависеть от внешних переменных и должны почти всегда существовать в пространстве имен. Вместо того чтобы создавать классы только для того, чтобы сгруппировать статические функции, которые не используют общие статические данные, используйте пространства имен. Draks 17.05.13 в 13:45 |
||
|
Функции, определяемые в той же единице компиляции, что и классы могут ввести ненужные зависимости связанности и линковки при непосредственном вызове другими единицами компиляции; статические члены функции особенно восприимчивы к этому. Рассмотрите разработку нового класса или размещение функций в пространстве имен возможно в отдельной библиотеке. Draks 17.05.13 в 14:01 |
||
|
Если Вы должны определить функцию, не являющуюся членом, и она необходима только в .cc файле, используйте неименованное пространство имен или статическую линковку (например, static int Foo() {...}), чтобы ограничить ее видимость. Draks 17.05.13 в 14:06 |
||
|
Локальные переменные Draks 17.05.13 в 14:15 |
||
|
Располагайте переменные функции в наиболее узкую область видимости, и инициализируйте переменные в объявлении. Draks 17.05.13 в 14:15 |
||
|
C++ позволяет объявлять переменные где угодно в функции. Мы советуем Вам объявлять их в максимально локальной области видимости, и максимально близко к первому использованию. Это упрощает для читателя находить объявление и видеть каким типом является переменная, и чем она проинициализирована. В частности, инициализация должна использоваться вместо объявления и присваивания, например: Draks 17.05.13 в 14:26 |
||
|
Следует отметить, что GCC реализует for (int i = 0; i < 10; ++i) правильно (область видимости i является только область видимости цикла for), так что затем можно использовать i в другом цикле в той же области видимости. Это также правильно для областей видимости операторов if и while, например, Draks 17.05.13 в 14:31 |
||
|
Существует один нюанс: если переменная является объектом, его конструктор вызывается каждый раз, как переменная входит в область видимости и объект создается, а его деструктор вызывается каждый раз, когда она выходит из области видимости. lyzov 17.08.13 в 16:30 |
