C ++ доступ к переменным из файлов .CPP - PullRequest
4 голосов
/ 07 сентября 2010

Я немного размышляю о том, как работает переменный доступ между файлами .cpp. Например:

main.cpp

int main()
{
    int a = i;
    return 0;
}

main2.cpp

int i;

Это генерирует ошибку компилятора в main.cpp, сообщая мне, что в i его нет. Какая разница тогда, ключевое слово "static" делает в этом контексте? (Я попробовал Googling для этого, но большинство информационных страниц «статического ключевого слова» говорят о классах и функциях)

main2.cpp

static int i;

Это то же самое? Предотвращает ли он использование extern int i для доступа к i в другом месте? Чем отличается использование анонимных пространств имен при обработке переменных?

main2.cpp

namespace
{
    int i;
}

Подводя итог:

  • Можно ли получить доступ к переменным между файлами .cpp? (кроме ключевого слова extern)
  • Как ключевое слово static для глобальной переменной влияет на вещи?
  • Как анонимные пространства имен по-разному влияют на вещи?

Ответы [ 3 ]

2 голосов
/ 07 сентября 2010

В первом примере main2.cpp определяет глобальную переменную i, к которой может иметь доступ с помощью main.cpp, если в этом файле появилось объявление extern о i.(Обычно это объявление extern происходит из заголовочного файла.) Вы получили ошибку компилятора, потому что i никогда не был объявлен в main.cpp, что означает, что компилятор предполагает, что такой переменной нет.

В вашемво втором примере main2.cpp определяет область действия файла переменная i.Переменные области видимости файла отличаются от глобальных, даже если они имеют одинаковые имена.Если бы у вас во втором примере было внешнее объявление i в main.cpp, оба файла успешно скомпилировали бы 1019 *, но тогда вы бы получили ошибку ссылки, потому что global * 1021 отсутствует* переменная i была определена.

Если вы переименовали main2.cpp из второго примера в main3.cpp, добавили внешнее объявление i в main.cpp, скомпилировали все три и связали их все вместе, что бы добиться успеха;main.cpp и main2.cpp будут использовать одну переменную с именем i, а main3.cpp будет иметь собственную полностью отдельную переменную, также называемую i.

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

Значение анонимного пространства имен заключается в том, что вы можете поместить в него определение класса , и это делает все методы класса локальными для файлов.(Только блок class { ... } должен быть внутри блока namespace { ... }, чтобы получить этот эффект.) Вы не можете сделать это другим способом.

1 голос
/ 07 сентября 2010

Все глобальные переменные имеют своего рода связь .extern требуется связывание для именования одной и той же переменной в разных контекстах между разными файлами.

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

extern int i; // i exists somewhere in some .cpp file.
int i; // ah! this is the file it exists in. 
       // (Although nothing special about that.)

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

Исключение из правила static, означающее, что file-local находится в классах и inline функциях.Члены класса static должны более правильно называться extern, так как семантика идентична.Это уродливо и запутанно, но я предполагаю, что Бьярне просто хотел исключить extern в качестве ключевого слова.

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

0 голосов
/ 07 сентября 2010
  • да, например, вы можете использовать статические переменные класса
  • делает переменную локальной и постоянной для единицы компиляции
  • анонимное пространство имен предотвращает столкновение между символами. это как если бы вы создали пространство имен с уникальным именем вручную
...