2013-07-26 2 views
-5

На языке C++ существует ли какой-либо недостаток объявления переменной global?Есть ли недостаток, чтобы объявить переменную global?

void foo() 
{ 
    int a; 
    a=10; 
} 

int a; 
void foo() 
{ 
    a=10; 
} 

Любые разногласия между ними?

+2

Да, его область действия * глобальная *. Этого достаточно, чтобы избежать их, когда это возможно. – chris

+0

Итак, shoul объявляю все переменные глобальными? Таким образом, нам не нужно будет также использовать параметры функции. – noDispName

+0

Вы не должны. Функция ДОЛЖНА иметь параметры, а не глобальные переменные. – Darthman

ответ

12

Why Global Variables Should Be Avoided When Unnecessary

  • Нелокальность - Исходный код легче понять, когда сфера ее отдельных элементов ограничены. Глобальные переменные могут быть прочитаны или изменены любой частью программы, что затрудняет или объясняет все возможные варианты использования.
  • Контроль доступа или ограничение контроля - глобальную переменную можно получить или установить любой частью программы, а любые правила ее использования можно легко сломать или забыть. (Другими словами, get/set accessors , как правило, предпочтительнее прямого доступа к данным, а это еще и для ). Кроме того, отсутствие контроля доступа значительно затрудняет достижение безопасности в ситуациях, когда вы, возможно, захотите запустить ненадежный код (например, работать с сторонними плагинами).
  • Неявная связь - Программа со многими глобальными переменными часто имеет плотные связи между некоторыми из этих переменных и связывает между переменными и функциями. Группирование связанных элементов в единые единицы обычно приводит к улучшению программ.
  • Проблемы с параллелизмом - если доступ к глобальным переменным осуществляется несколькими потоками выполнения, необходима синхронизация (и слишком часто игнорируется). При динамической компоновке модулей с глобалами составная система может быть небезопасной, даже если два независимых модуля, протестированных в , десятки различных контекстов были безопасными.
  • Пространство имен - Глобальные названия доступны везде. Вы можете неосознанно в конечном итоге использовать глобальный, когда думаете, что используете локальный (путем орфографии или забывания объявить локальный) или наоборот . Кроме того, если вам когда-либо понадобится связывать модули, имеющие имена глобальных переменных, если вам повезет, вы получите ссылку ошибок. Если вам не повезло, компоновщик будет просто рассматривать все виды использования с тем же именем, что и тот же объект.
  • Проблемы с распределением памяти - В некоторых средах есть схемы распределения памяти, которые делают распределение глобальных комбинаций сложным. Это, в частности, истинно в языках, где «конструкторы» имеют побочные эффекты, отличные от . (В этом случае вы можете выражать небезопасные ситуации , где две глобальные зависимости взаимно зависят друг от друга). Кроме того, когда динамически связывает модули, может быть неясно, являются ли разные библиотеки собственными экземплярами глобальных переменных или общие глобальные значения .
  • Тестирование и конфайнмент - источник, который использует глобалы, несколько сложнее проверить, потому что невозможно установить «чистую» среду между прогонами. В более общем случае источник, который использует глобальные службы любого типа (например, чтение и запись файлов или баз данных) , которые явно не предоставлены этому источнику, трудно проверить по той же причине. Для коммуникационных систем способность тестировать системные инварианты может потребовать одновременного запуска более одной «копии» системы , что сильно затрудняет любое использование общих служб , включая глобальную память, которые не предусмотрены для обмена как часть теста.
+7

Я не думаю, что вы набрали это; было бы неплохо привести источник внизу. – mpen

+0

Помните, если я переформатирую это, чтобы использовать заголовки? Это выглядит намного лучше imo. ([Вот тестовая уценка, чтобы увидеть] (http://pastebin.com/MHpc9Rdn)) – chris

+0

очень хорошая ссылка - очень приятная информация в любом случае –

0

Использование памяти. В первом случае память будет освобождена, во втором - нет. И из этого очень плохо объявить переменную с именем типа '' A '' как глобальную переменную. Это будет источником большого количества ошибок.

+0

Будет освобожден? Я не думаю, что у C++ есть сборщик мусора. – noDispName

+0

@kutluhanmetin Переменные, объявленные в стеке (не указатели, локальные переменные), освобождаются при выходе из области видимости. На самом деле вы не можете удалить их, если попытаетесь. – mpen

+0

В сборщике мусора нет необходимости освобождать память для простых типов, таких как int. Если вы будете использовать классы в качестве глобальных переменных, он не будет освобожден от cc. – Darthman

1

памяти Global переменной автоматически не освобождается. Пока scope память переменной освобождается сразу после завершения блока.

void foo() 
{ 
    int a; 
    a=10; 
} 

Этот int a будет освобождена после завершения foo

int a; 
void foo() 
{ 
    a=10; 
} 

Этот int a будет освобожден в зависимости от его объема за пределами foo()

+1

Они все еще убираются после. – chris

0

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

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

Существует третий вариант. Если вы сделаете это:

void foo() 
{ 
static int a; 
a=10; 
} 

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

0

Это обсуждалось ранее в StackOverflow. Смотрите, например этого:

https://stackoverflow.com/a/485020/980195

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

Кроме того, помещение его в глобальное пространство имен означает, что оно может вызвать столкновения имен, неоднозначность или даже пользователей, случайно ссылающихся на неправильную переменную с помощью простой опечатки. Это особенно плохо, если вы называете вашу переменную чем-то простым, как в вашем случае.

Есть и другие причины, например, посмотрите на предоставленный ответ @naren.

Смежные вопросы