Что именно означает «статический» при объявлении «глобальных» переменных в C ++? - PullRequest
5 голосов
/ 05 августа 2010

Это расширение области моего предыдущего вопроса .

Что такое «статический», как он используется и какова цель использования «статического» при работе с C ++?

Спасибо.

Ответы [ 6 ]

13 голосов
/ 05 августа 2010

Это означает, что переменная является локальной для единицы перевода (проще говоря, для одного исходного файла) и недоступна извне.Такое использование статического кода фактически не рекомендуется в текущем стандарте C ++ - вместо этого вы должны использовать анонимные пространства имен:

static int x = 0;    

должно быть:

namespace {
    int x = 0;    
}
10 голосов
/ 05 августа 2010

Ключевое слово static имеет разные значения в C ++, в зависимости от контекста.

Когда объявляется свободная функция или глобальная переменная, это означает, что функция не должна быть доступна вне этой единственной единицы перевода:

// test.cpp
static int a = 1;
static void foo() {}

Если результат компиляции этой единицы перевода связан с другой единицей перевода, содержащей символы a и foo, это не нарушит правило единого определения, как в этой конкретной единице перевода a и foo приват символов. Это использование было отменено безымянными пространствами имен.

// test2.cpp
namespace {
   static int a = 1;
   static void foo() {}
}

Когда объявляется локальная переменная внутри функции, это означает, что время жизни переменной будет увеличиваться от первого вызова функции до конца программы, а не только на время вызова:

int foo() {
   static int counter = 0;
   return ++counter;
}
int main() {
  for ( int i = 0; i < 10; ++i ) { 
     std::cout << foo() << std::endl;
  }
}

В предыдущем коде counter инициализируется один раз, когда foo вызывается впервые, но переменная переживет функцию и сохранит значение при различных вызовах функций. В предыдущем коде будет напечатано «1 2 3 4 ... 10». Если переменная не была объявлена ​​static, то результатом будет «1 1 1 ... 1».

В пределах области видимости static означает, что член является членом класса, а не конкретного экземпляра. Это использование эквивалентно использованию в вашем другом вопросе: использование этого конкретного члена не связано ни с каким конкретным объектом.

struct test {
   int x;
   static int y;
};
int test::y;       // need to define it in one translation unit
int main() {
   // test::x = 5; // !error cannot access a non-static member variable
                   // without an instance
   test::y = 5;    // ok
   test t, other;
   t.x = 10;       // ok
   t.y = 15;       // ok, the standard allows calling a static member through
                   // an instance, but this is the same as test::y
}

В этом случае член x является нестатическим атрибутом члена, и поэтому для каждого экземпляра класса есть разные x. В примере программы t.x и other.x относятся к разным целым числам. С другой стороны, y - это static, и поэтому в программе есть единственный экземпляр test::y. Даже если стандарт позволяет вызывать t.y и other.y, оба использования относятся к одной и той же переменной. То же самое касается методов членов. Если они статические, они являются методами уровня класса и могут вызываться без экземпляра, тогда как если они нестатические, они применяются к конкретному экземпляру, и должен использоваться синтаксис a.b или a->b.

Это использование static аналогично использованию одного и того же ключевого слова в Java, тогда как два других не присутствуют на этом языке. Существует одно использование ключевого слова в Java, которого нет в C ++, и это использование статических инициализаторов классов (блок кода на уровне класса, окруженный static { ... }). В Java этот блок кода будет выполняться при загрузке класса и только один раз. Инициализация статических переменных-членов в C ++ должна выполняться в инициализаторе определения переменной.

6 голосов
/ 05 августа 2010

Этот материал, кажется, довольно хорошо охвачен здесь .

Но, перефразируя, в C

  1. есть 2 варианта использования * Предотвращение использования глобальногопеременная вне области действия файла, который ее определяет.
  2. Разрешить локальным переменным внутри функции сохраняться при вызове функции, как в

    int getNextId () {static int id= 0;вернуть id ++;}

C ++ наследует оба из них и добавляет два собственных использования.

  1. статические переменные-члены: переменные, которые являются «общими» для всех экземпляровкласс, а также может быть доступ без ссылки на экземпляр класса.Общий доступ кажется неправильным словом, но, по сути, я считаю, что в результате любая ссылка на статическую переменную-член ссылается на одно и то же место в памяти.
  2. статические методы: методы, которые можно вызывать без ссылки на конкретный экземпляркласса, который его определяет.
2 голосов
/ 05 августа 2010

Статика в основном означает, что переменная связана с временем жизни программы, а не с какой-либо конкретной функцией или экземпляром класса. Когда вы должны его использовать? Не. Какова цель? Отладка данных, в основном.

Как правило, в C ++, если вы используете статические данные, вы сделали это неправильно. Бывают моменты, когда это уместно, но они очень редки.

1 голос
/ 05 августа 2010

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

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

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

0 голосов
/ 05 августа 2010

Статические члены класса - это данные и функции, которые связаны с самим классом, а не с объектами класса.

В следующем примере класс Fred имеет статический член данных x_ и данные экземпляра.член y_.Существует только одна копия Fred :: x_ независимо от того, сколько объектов Fred создано (включая объекты Fred), но существует один y_ на объект Fred.Таким образом, говорят, что x_ ассоциируется с классом, а y_ ассоциируется с отдельным объектом класса.Аналогично класс Fred имеет статическую функцию-член f () и экземплярную функцию-член g ().

class Fred {
    public:
        static void f() throw();                           <-- 1
        void g() throw();                                  <-- 2
    protected:
        static int x_;                                     <-- 3
        int y_;                                            <-- 4
};

(1) Функция-член, связанная с классом

(2) Функция-член, связаннаяс отдельным объектом класса

(3) Член данных, связанный с классом

(4) Член данных, связанный с отдельным объектом класса

Использование:

Когда вы хотите отслеживать количество экземпляров созданного класса, вы используете статическую переменную.Например, в классе 'Car' каждый экземпляр Car может иметь уникальный серийный номер (в данном случае _y), и компания может захотеть отслеживать количество произведенных автомобилей (в данном случае _x).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...