Статьи

C ++ лаконично: пространства имен

Давайте подробно рассмотрим пример.

Пример: GlobalNamespaceSample \ GlobalNamespaceSample.cpp

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
#include <ostream>
#include «../pchar.h»
 
int g_x = 10;
 
int AddTwoNumbers(int a, int b)
{
    return a + b;
}
 
int _pmain(int /*argc*/, _pchar* /*argv*/[])
{
    int y = 20;
    std::wcout << L»The result of AddTwoNumbers(g_x, y) where g_x = » <<
        g_x << L» and y = » << y << L» is » << AddTwoNumbers(g_x, y) <<
        L».»
 
    if (true == 1)
    {
        std::wcout << L»true == 1!»
    }
    return 0;
}

В предыдущем примере мы определили две функции: AddTwoNumbers и wmain . Эти две функции находятся в глобальном пространстве имен. Глобальное пространство имен — это базовый уровень, на котором существует все остальное в программе. C ++, благодаря своему наследию C, позволяет вам определять что угодно в глобальном пространстве имен (поэтому вы можете определять пространства имен, классы, структуры, переменные, функции, перечисления и шаблоны).

C # также имеет концепцию глобального пространства имен, но он не позволяет вам определять что-либо внутри него, кроме пространств имен и типов. В предыдущем примере у нас есть оператор int g_x = 10; который определяет целое число с именем g_x в глобальном пространстве имен и присваивает ему значение 10. Это то, что обычно называют глобальной переменной. В C # глобальные переменные недопустимы.

Короче говоря, у каждого языка программирования, с которым я когда-либо работал, есть свои плохие функции — вещи, которые позволяет язык, но вещи, которые обычно приводят к проблемам. Эти проблемы включают трудные для отладки проблемы, тонкие ошибки, которые остаются незамеченными в течение длительного времени, проблемы с удобством сопровождения, проблемы с читаемостью и все другие неприятные вещи, которые добавляют много часов к времени разработки без какой-либо выгоды. С ++ ничем не отличается. Когда мы сталкиваемся с чем-то, что соответствует этому описанию, я сделаю все возможное, чтобы высказать это. Это один из тех моментов.

Глобальные переменные плохие. Избегайте их, когда это возможно. При использовании их в C ++ существует общее соглашение, заключающееся в том, что перед именем переменной стоит префикс g_, как в предыдущем примере. Хотя это помогает предупредить вас и других программистов о том, что это глобальная переменная, это не меняет того факта, что это глобальная переменная, и имеет все проблемы, которые я описал. Это не книга о плохих практиках программирования, поэтому я не собираюсь тратить время на объяснение, почему глобальные переменные плохие. Все, что вам нужно знать, это то, что эта функция существует в C ++, но вы должны избегать ее использования, когда это возможно.


В C ++ :: является оператором разрешения области видимости. Он используется для отделения вложенных пространств имен, для отделения типов от их пространства имен и для отделения функций-членов и переменных от их типа.

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

  • Определение функции-члена.
  • Доступ к члену базового класса в определении функции-члена.
  • Доступ к статической функции-члену или переменной.
  • Присвоение значения статической переменной-члену.
  • Получение адреса функции-члена.

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

Это может показаться сложным, поскольку C # просто использует. оператор для всех целей, которые ::,., и -> используются в C ++.

Примечание: мы обсудим и -> операторы позже. Сейчас вам просто нужно знать, что они используются для доступа к переменным-членам экземпляра и нестатическим функциям-членам (которые вы используете в зависимости от того, работаете ли вы с указателем или нет).

По большей части, вы будете в порядке. Единственное место, где вы можете запутаться, это если вы попытаетесь получить доступ к члену базового класса с помощью. оператор, а не оператор ::, или если вы пытаетесь указать член перечисления, используя что-то отличное от ::. Если вы когда-нибудь скомпилируете программу и получите синтаксическую ошибку с жалобой на «отсутствует»; ‘ перед ‘.’ «Хорошая ставка, которую вы использовали. где вы должны были использовать :: вместо.


Пространство имен определяется почти так же, как и в C #. Вот пример:

Образец: NamespacesSample \ NamespacesSample.cpp

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <iostream>
#include <ostream>
#include <string>
#include «../pchar.h»
 
using namespace std;
 
namespace Places
{
    namespace Cities
    {
        struct City
        {
            City(const wchar_t* name)
            {
                Name = wstring(name);
            }
 
            wstring Name;
        };
    }
}
 
int _pmain(int /*argc*/, _pchar* /*argv*/[])
{
    auto nyc = Places::Cities::City(L»New York City»);
 
    wcout << L»City name is » << nyc.Name.c_str() << L».»
 
    return 0;
}

Примечание. Никогда не включайте директиву using в заголовочный файл. Если вы сделаете это, вы не просто импортируете типы и пространства имен в этом пространстве имен в файл заголовка, вы также импортируете их в любой исходный файл или файл заголовка, который включает файл заголовка. Это вызывает действительно неприятные проблемы загрязнения пространства имен. Далее мы будем обсуждать заголовочные файлы, поэтому все, что неясно по этому поводу, должно иметь смысл. Просто помните, что наличие директивы using namespace в заголовочном файле — плохая идея; используйте их только в файлах исходного кода.

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

Этот урок представляет собой главу из C ++ Succinctly , бесплатной книги от команды Syncfusion .