Всегда ли глобальные переменные - это плохо ?
От: Forrest_Gump  
Дата: 02.03.04 18:54
Оценка:
Собственно вопрос.

Есть ли такие случаи, когда без глобальных переменных не обойтись ?

Хотелось бы услышать мнение тех, кто имеет опыт разработки более-менее крупных проектов.

Интересно также услышать ответ на вопрос отдельно в контексте C и C++.
Re: Всегда ли глобальные переменные - это плохо ?
От: kaligula Удмуртия http://zant.glazov.net
Дата: 02.03.04 22:01
Оценка:
Здравствуйте, Forrest_Gump, Вы писали:

F_G>Собственно вопрос.


F_G>Есть ли такие случаи, когда без глобальных переменных не обойтись ?


Таких случаев нет!
И что б не ломать голову, пытаясь придумать подобный случай, вот тебе простенький "патч" :

foreach($_GET as $key => $value)
{
  $tmp = $key;
  $$tmp = $value;
}
В Майкрософт лохов не держат, их разводят (с) ...
Re: Всегда ли глобальные переменные - это плохо ?
От: Шахтер Интернет  
Дата: 03.03.04 00:59
Оценка: 2 (1) +1
Здравствуйте, Forrest_Gump, Вы писали:

F_G>Собственно вопрос.


F_G>Есть ли такие случаи, когда без глобальных переменных не обойтись ?


Конечно. Собственно говоря, глобальная переменная на новомоязе -- это синглетон. Практически в любом проекте есть объекты, которые по смыслу существуют в одном экземпляре и которые широко используются во всём проекте. Например -- подсистема для ведения log а. А ввод-вывод? cin и cout -- типичные синглетоны. Главное окно в оконном приложении. и.т.п.

Никакого криминала в использовании глобальных переменных нет. Просто не надо увлекаться.
... << RSDN@Home 1.1.0 stable >>
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[2]: Всегда ли глобальные переменные - это плохо ?
От: Евгений Коробко  
Дата: 03.03.04 06:23
Оценка: 7 (1)
Некоторое уточнение: все эти объекты не должны быть глобальными, т.е. не должны быть в global scope. Они должны быть либо в namespace, либо статическим полем класса.
Во-вторых, часто разумнее сделать следующее. Вместо глобальной переменной
int x;
сделать
int& get_x()
{
static int x;
return x;
}

Во-первых, инкапсуляция, а во-вторых, решает проблему с упорядочиванием инициализации глобальных переменных. Дело в том, что если глобальные переменные описаны в разных единицах трансляции, то порядок вызова их конструкторов не определён.
Posted via RSDN NNTP Server 1.8 beta
Евгений Коробко
Re[3]: Всегда ли глобальные переменные - это плохо ?
От: Шахтер Интернет  
Дата: 04.03.04 03:07
Оценка: 1 (1) -1
Здравствуйте, Евгений Коробко, Вы писали:

ЕК>Некоторое уточнение: все эти объекты не должны быть глобальными, т.е. не должны быть в global scope. Они должны быть либо в namespace, либо статическим полем класса.


Слово должен здесь не уместно. Можно сказать -- хорошо бы. Правда, в C такое невозможно. А в C++ , да не следует без особой необходимости засорять global scope.

ЕК>Во-вторых, часто разумнее сделать следующее. Вместо глобальной переменной

ЕК>int x;
ЕК>сделать
ЕК>int& get_x()
ЕК>{
ЕК> static int x;
ЕК> return x;
ЕК>}

У этого подхода довольно большие накладные расходы. Во-первых, на вызов функции, во-вторых, если x будет иметь нетривиальный конструктор, то компилятор создаст скрытый флажок, который будет проверяться при каждом вызове функции для того, чтобы определить момент первого вызова и сделать в этом случае вызов конструктора. Это создаёт проблему в многопоточных приложениях.

ЕК>Во-первых, инкапсуляция, а во-вторых, решает проблему с упорядочиванием инициализации глобальных переменных. Дело в том, что если глобальные переменные описаны в разных единицах трансляции, то порядок вызова их конструкторов не определён.


Если вы завернули эти объекты в функции то тоже не определён.
Если вы хотите создать несколько глобальных объектов в определённом порядке, следует поместить определения этих объектов в один файл. Во всяком случае, это лучшее, что можно сделать. А по-хорошему, не стоит создавать зависимостей такого сорта. Если уж очень нужно, то лучше проводить инициализацию объектов в два этапа. Конструктор должен делать минимальную работу, переводя объект в нулевое состояние, а для рабочей инициализации стоит использовать инициализирующий метод. И вызывать эти методы в правильном порядке в начале main. Дополнительный бонус -- можно перехватывать исключения. Бонус два -- можно параметризовать вызовы инициализирующих функций аргументами командной строки, например, или запросив у пользователя параметры.
... << RSDN@Home 1.1.0 stable >>
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re: Всегда ли глобальные переменные - это плохо ?
От: PK Sly http://www.vocord.ru/
Дата: 04.03.04 10:14
Оценка: -1
Это — бред из серии "никогда под страхом смертной казни не используйте goto".
VAX/VMS rulez!
Re[2]: Всегда ли глобальные переменные - это плохо ?
От: _Jane_ Украина  
Дата: 09.03.04 11:44
Оценка: 8 (1)
Здравствуйте, PK Sly, Вы писали:

PS>Это — бред из серии "никогда под страхом смертной казни не используйте goto".


А потом сидишь и копаешься в куче этих глобальных переменых и переходов куда попало Мне как-то пришлось... в чужом коде рыться, вот таком противном.
Глобальные переменные — это ОТСТОЙ!!!
С тех пор, у меня к защитникам глобальных переменных отношение не очень хорошее. Их можно позволить парочку, если очень надо. но я бы запретила многие злоупотребляют этим. Ну да, это ж если что прототип функции надо менять, или новую заводить, а тут завел глобальную и все дела. А потом поди разберись в этой каше.
Jane
Re[3]: Всегда ли глобальные переменные - это плохо ?
От: Аноним  
Дата: 09.03.04 13:06
Оценка:
_J_>Глобальные переменные — это ОТСТОЙ!!!

Вот тут как раз я спрашивал про метрики Харрисона и Кукак. А на сколько это отстой т.е на сколько это увеличивает сложность подпрограммы

Хоррисон и Кук говорят, что на

G(i)*(n-1)*V(G)(i) т.е если V(G) = 10 ( число базовых путей в программе) и есть 3 модуля (n =3) и используется одна переменная то

1*(3-1)*10 = 20 т.е при этом сложность такой подпрограммы увеличивается в 2 раза!!
Re[4]: Всегда ли глобальные переменные - это плохо ?
От: _Jane_ Украина  
Дата: 09.03.04 14:00
Оценка:
Здравствуйте, Аноним, Вы писали:

_J_>>Глобальные переменные — это ОТСТОЙ!!!


А>Вот тут как раз я спрашивал про метрики Харрисона и Кукак. А на сколько это отстой т.е на сколько это увеличивает сложность подпрограммы


Если честно я теорией не заморачивалась мне пришлось на практике работать с программой в которой была просто огромная куча глобальных переменных. Сразу оговорюсь — это был чистый C без плюсов.
Очень тяжело.
Многие проблемы, которые при нормальном коде — параметры функций, правильное применение const модификаторов — отслеживались просто по коду, так приходилось дебажить. Много и долго.

Я глянула одним глазом про метрики, похоже они придуманы для функционального программирования. А в ООП ведь есть еще статические члены классов, тоже каким-то боком глобальные А давно эта мера была придумана?
Jane
Re: Универсальный способ избавления от глобальных переменных
От: S.Yu.Gubanov Россия http://sergey-gubanov.livejournal.com/
Дата: 31.08.04 15:10
Оценка: 5 (1)
Здравствуйте, Forrest_Gump, Вы писали:

F_G>Есть ли такие случаи, когда без глобальных переменных не обойтись ?


Есть универсальный очень простой способ избавления от глобальных переменных.

Начнем с простого и всем известного:

Имеем код:
VAR
  g: INTEGER;

PROCEDURE DoSmth();
BEGIN
  g := 1;
END;

превращаем его в код:
TYPE
  TMyType = CLASS
    g: INTEGER;
    PROCEDURE DoSmth; 
  END;

PROCEDURE TMyType.DoSmth;
BEGIN
  SELF.g := 1;
END;

Спрашивается что мы сделали? Переменная g — была контекстом исполнения процедуры DoSmth. Мы взяли и соединили данные и методы в одно целое — получили то что в рамках ООП называется объектом. Все тривиально.

Следующий шаг: — у нас есть уже не просто процедуры и глобальные переменные, а теперь есть объекты и глобальные переменные. Однако что нам мешает повторить еще раз тот самый первый шаг, но уже на более высоком уровне абстракции? Каждый объект живет в каком-то контексте глобальных переменных. Вот мы берем и объявляем этот контекст глобальных переменных другим объектом — Context (Domain, Document, Environment,...)
TYPE
  Context = CLASS
    GlobalX: INTEGER;
    GlobalY: INTEGER;
    GlobalZ: INTEGER;
  END;
 

  TMyType = CLASS
    FContext: Context
    g       : INTEGER;
    CONSTRUCTOR Create(c: Context);
  END;

Если на первом шаге мы соединили вместе данные и процедуры получив объект, то на втором шаге мы соединили объект и его контекст — тоже объект в рамках которого тот первый объект живет. И так можно двигаться дальше: к Context-у присоединить Domain в котором он определен, к Domain-у присоединить Document в рамках которого он существует и т.д. Получается иерархическая структура контекстов существования.
TYPE
  Environment = CLASS
    //...
  END;
 

  Document = CLASS
    FEnvironment: Environment;
    //...
    CONSTRUCTOR Create(e: Environment); 
  END;


  Domain  = CLASS
    FDocument: Document;
    //...
    CONSTRUCTOR Create(d: Document); 
  END;


  Context = CLASS
    FDomain: Domain;
    //...
    CONSTRUCTOR Create(d: Domain); 
  END;
 

  TMyType = CLASS
    FContext: Context
    //...
    CONSTRUCTOR Create(c: Context);
  END;

                             Domain
                            /       
                          /         
                  Document---Domain
                 /        \                                   TMyType
                /          \                                /
               /             Domain                       /
              /                           /Context      /
             /               Domain     /             /   
            /               /         /             /
           /              /         /             /
Environment-------Document---Domain--------Context-------------TMyType
           \              \        \              \
            \               \        \              \
             \               Domain    \              \
              \                          \              \
               \             Domain        Context        \
                \           /                               \ 
                 \        /                                   \TMyType...
                  Document---Domain
                          \              
                           \            
                             Domain


Вот. А начиналось все с того что люди объединили данные и процедуры в одно целое и назвали это объектом. Затем осталось только вкладывать одни объекты внутрь других как матрешки... — и ни одной глобальной переменной больше не нужно.
Re: Всегда ли глобальные переменные - это плохо ?
От: sluge  
Дата: 31.08.04 16:07
Оценка:
я считаю что нет. ну невиноваты глобальные перемнные в том что их менеджеры не любют иногда они очень удобны
Re: Всегда ли глобальные переменные - это плохо ?
От: Gaperton http://gaperton.livejournal.com
Дата: 31.08.04 16:39
Оценка:
Здравствуйте, Forrest_Gump, Вы писали:

F_G>Собственно вопрос.


F_G>Есть ли такие случаи, когда без глобальных переменных не обойтись ?

F_G>Хотелось бы услышать мнение тех, кто имеет опыт разработки более-менее крупных проектов.
F_G>Интересно также услышать ответ на вопрос отдельно в контексте C и C++.
Для C++ лучше любыми способами избегать глобальных переменных, особенно для представления сложных типов. Грабли.
Вместо них лучше использовать статические члены класса.

По сути дела, та же глобальная переменная. Но...
class Singleton
{
    static Singleton * s_pInstance; // = 0;
    Singleton();
    Singleton( const Singleton & );
public:
    Singleton & Instance()
    {
        if( !s_pInstance )
            s_pInstance = new Singleton();

        return *s_pInstance;
    }
}

...избавляет от проблем с порядком инициализации. Особенно в крупных и затяжных проектах.
Re[2]: Всегда ли глобальные переменные - это плохо ?
От: Sinclair Россия https://github.com/evilguest/
Дата: 01.09.04 05:23
Оценка: 8 (1)
Здравствуйте, sluge, Вы писали:

S>я считаю что нет. ну невиноваты глобальные перемнные в том что их менеджеры не любют иногда они очень удобны

Виноваты-виноваты. Глобальные переменные виновны в появлении неявных зависимостей. А менеджеры именно их не любят, т.к. собственно их работа и состоит в управлении зависимостями.
... << RSDN@Home 1.1.4 beta 1 >>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[2]: Всегда ли глобальные переменные - это плохо ?
От: dshe  
Дата: 01.09.04 11:14
Оценка:
Здравствуйте, Gaperton, Вы писали:

G>Здравствуйте, Forrest_Gump, Вы писали:


F_G>>Собственно вопрос.


F_G>>Есть ли такие случаи, когда без глобальных переменных не обойтись ?

F_G>>Хотелось бы услышать мнение тех, кто имеет опыт разработки более-менее крупных проектов.
F_G>>Интересно также услышать ответ на вопрос отдельно в контексте C и C++.
G>Для C++ лучше любыми способами избегать глобальных переменных, особенно для представления сложных типов. Грабли.
G>Вместо них лучше использовать статические члены класса.

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

Re: Singleton or static
Автор: dshe
Дата: 07.05.04
--
Дмитро
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.