namespace и оператор ::

Сразу пример , прояcняющий область видимости нескольких разных переменных ii в одном с файле:

Оператор :: это так называемое разрешение области видимости.

#include 
#include "stdio.h"

int ii; // глобальная переменная 

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    int ii=123; // локальная переменная в функции

    printf("ii=%d\n",ii);

    for(int jj=0;jj<5;jj++)
    {
        int ii=0;  // локальная переменная в цикле в функции
        printf("%d %d\n" , ii++ , ::ii++);
    }

    return a.exec();
}

Вывод:

ii=123
0 0
0 1
0 2
0 3
0 4

Самый интересный момент это применение :: перед ii.
::ii означает использование ii из глобальной области видимости.

Теперь совет всем кто программирует придумайте "уникальное" кодовое слово своим исходникам и обзовите им как свою собственную область видимости, чтобы хоть как-то гарантировать, что названия ваших глобальных переменных, функции и т.д. на совпадет с названиями из других чужих (и даже своих) проектов.

Например выбираем слово ququ.

#include "stdio.h"

int ii=123;

namespace ququ{
    int ii=10;
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    int ii=123;

    printf("ii=%d\n",ii);

    for(int jj=0;jj<5;jj++)
    {
        int ii=0;
        printf("%d %d %d\n" , ii++ , ::ii++ , ququ::ii++);
    }

    return a.exec();
}

Вывод:

ii=123
0 123 10
0 124 11
0 125 12
0 126 13
0 127 14

Использование оператора ququ::ii кроме защиты еще подсказывает к какой теме относится переменная ii (на наш взгляд очень удобно).

Кстати говоря классы тоже имеют :: в коде и это тоже по сути то же самое применение.

class A
{
    public:
    A()
    {
        ii=99;
        printf("constructor A ii=%d\n",ii);
    }

    ~A();

    void method1()
    {
        printf("method1 A ii=%d\n",ii);
    }

    int ii;
    static int si=0;
};

A::~A()  
{
    printf("destructor A ii=%d\n",ii);
}
// объявление диструктора вынесено из тела класса А 
// и поэтому сразу появляется оператор ::
// чтобы понять к какому классу (к какой области видимости) 
// относится этот диструктор (метод)

int A::si=0;

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    A aaa;
    aaa.ii=2;

    return a.exec();
}

На наш взгляд все логично и правильно.

В коде есть static int si=0; (переменная класса). Интересно , что static указывает использовать si один раз для всех экземпляров класса, то есть A могут создаваться многократно в коде , а вот si у них будет всегда один и размещен в .bss сегменте (это не куча и не стек , это фиксированных блок памяти , создаваемый на стадии линковки).

Так вот в коде оказывается для static переменных можно сразу инициализировать их без создания экземпляра класса :

int A::si=0;

Но только не в теле main , а как глобальную переменную вне main. Да и int в начале (A::si=0;) не забываем.