глобальные переменные в C ++ - PullRequest
5 голосов
/ 25 августа 2010

В многопоточном приложении C ++ со многими классами я пытаюсь выяснить, каковы методы определения глобальной переменной

  1. C-стиль, определите его как глобальный в любом исходном файле, определите его как extern в заголовке, который включен в классы, обращающиеся к этой переменной.

  2. Напишите класс Singleton, который содержит эти глобальные переменные и предоставляет методы set / get для записи в переменную.

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

Есть ли еще и лучшие способы?

Ответы [ 9 ]

4 голосов
/ 25 августа 2010

Прежде всего старайтесь избегать глобальных переменных настолько, насколько это возможно.Если вам просто нужно это сделать (например, это относится к cin, cout и cerr), ваш второй метод, безусловно, является лучшим (и более естественным) способом сделать это.

3 голосов
/ 25 августа 2010

Если область действия вашей «глобальной переменной» может быть сужена (что обычно имеет место - сколько переменных действительно глобальные?), То вы можете сделать его закрытым статическим членом класса в соответствующем классе-владельце. Если ваши другие классы должны увидеть его (или, что менее вероятно, обновить его), предоставьте методы доступа get / put.

3 голосов
/ 25 августа 2010

Я бы определенно пошел с классом Singleton. Это лучший способ обработки «глобальных» переменных в многопоточной среде ООП.

1 голос
/ 26 августа 2010

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

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

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

Так что это может показаться странным, но я бы предпочел первый метод.

1 голос
/ 25 августа 2010

Эта проблема может быть легко решена с помощью альтернативного метода.

C ++ очень легко решает эту проблему с помощью своего нового оператора :: , называемого оператором разрешения области видимости.Синтаксис следующий:

:: variable-name;

Этот оператор позволяет получить доступ к глобальной версии vriable.

1 голос
/ 25 августа 2010

Если вы должны использовать глобальную переменную (и почему вы ее используете?), Я рекомендую второй способ, который вы описали. Первый способ - это то, как вы можете столкнуться со всеми видами проблем с пространством имен.

0 голосов
/ 26 августа 2010

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

0 голосов
/ 25 августа 2010

Вы можете определить объект значения, который обертывает одну реализацию с помощью идиома handle / body.

Также ознакомьтесь с «Современным дизайном C ++» Александреску, чтобы обсудить трудности реализации синглтона в средах MT и способы их решения.

0 голосов
/ 25 августа 2010

Это зависит от рассматриваемой проблемы.

Глобальные возможности в стиле C имеют преимущество простоты: нет необходимости в вызове Singleton :: instance ().Однако Singleton :: instance () позволяет вам инициализировать ваше глобальное состояние при первом вызове.

Чтобы получить лучшее из обоих миров, используйте глобальные переменные в стиле C, инициализированные с помощью метода счетчика Шварца.http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Nifty_Counter

...