Статические переменные в C ++ - PullRequest
       28

Статические переменные в C ++

61 голосов
/ 13 сентября 2010

Я хотел бы знать, в чем разница между статическими переменными в заголовочном файле и объявленными в классе. Когда статическая переменная объявлена ​​в заголовочном файле, ее область действия ограничивается файлом .h или для всех модулей. Также обычно статическая переменная инициализируется в файле .cpp при объявлении в классе, верно? Так что же означает, что область действия статической переменной ограничена двумя единицами компиляции?

Ответы [ 3 ]

85 голосов
/ 13 сентября 2010

Извините, когда я отвечаю на ваши вопросы не по порядку, это облегчает понимание таким образом.

Когда в заголовочном файле объявляется статическая переменная, ее область действия ограничивается файлом .h или для всех модулей.

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

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

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

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

В объявлении класса static означает, что все экземпляры класса совместно используют эту переменную-член; то есть у вас может быть сотни объектов этого типа, но всякий раз, когда один из этих объектов ссылается на переменную static (или «класс»), это значение одинаково для всех объектов. Вы можете думать об этом как о «глобальном классе».

Также обычно статическая переменная инициализируется в файле .cpp при объявлении в классе, верно?

Да, одна (и только одна ) единица перевода должна инициализировать переменную класса.

Так что значит область действия статической переменной ограничена двумя единицами компиляции?

Как я уже сказал:

  • Заголовок не является единицей компиляции,
  • static означает совершенно разные вещи в зависимости от контекста.

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

Надеюсь, это поможет.

PS: Проверьте последний абзац ответа Чубсдада о том, как не следует использовать static в C ++ для обозначения внутренней связи, но для анонимных пространств имен. (Потому что он прав. ;-))

46 голосов
/ 13 сентября 2010

Статическая переменная в заголовочном файле:

скажем 'common.h' имеет

static int zzz;

Эта переменная 'zzz' имеет внутреннюю связь (Эта же переменная не можетбыть доступным в других единицах перевода).Каждая единица перевода, включающая 'common.h', имеет свой уникальный объект с именем 'zzz'.

Статическая переменная в классе:

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

$ 9.4.2 / 6 - «Статические члены-данные класса в области пространства имен имеют внешнюю связь (3.5).В локальном классе не должно быть статических элементов данных. "

Так, скажем, 'myclass.h' имеет

struct myclass{
   static int zzz;        // this is only a declaration
};

, а myclass.cpp имеет

#include "myclass.h"

int myclass::zzz = 0           // this is a definition, 
                               // should be done once and only once

и "hisclass.cpp" имеет

#include "myclass.h"

void f(){myclass::zzz = 2;}    // myclass::zzz is always the same in any 
                               // translation unit

, а "ourclass.cpp" имеет

#include "myclass.h"
void g(){myclass::zzz = 2;}    // myclass::zzz is always the same in any 
                               // translation unit

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

Примечание: использование «static» для объявления переменной области файла устарело, а безымянное пространство имен является лучшей альтернативой

14 голосов
/ 13 сентября 2010

Статическая переменная, объявленная в файле заголовка вне класса, будет file-scoped в каждом файле .c, который включает заголовок. Это означает, что отдельная копия переменной с тем же именем доступна в каждом из файлов .c, куда вы включаете файл заголовка.

С другой стороны, статической переменной класса является class-scoped, и эта же статическая переменная доступна для каждой единицы компиляции, которая включает заголовок, содержащий класс со статической переменной.

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