Подтвердить что ты не робот

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

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

4b9b3361

Ответ 1

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

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

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

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

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

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

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

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

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

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

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

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

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

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

PS: Проверьте последний параграф ответа Chubsdad, о том, как вы не должны использовать static в С++ для указания внутренней привязки, но анонимных пространств имен. (Потому что он прав.;-))

Ответ 2

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

say '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

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

Примечание: использование 'static' для объявления переменная области файла устарела и неназванное пространство имен является превосходным Альтернативный

Ответ 3

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

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