2010-08-25 11 views
5

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

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

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

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

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

+8

Да, лучший способ - не использовать его. – Puppy

+0

О нет. Пожалуйста, нет. –

+1

Зачем вам нужны глобальные переменные? Это синхронизировать потоки, если это так, есть лучшие механизмы там. –

ответ

3

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

3

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

+0

Одноэлементный шаблон осложнен тем, что ему необходимо справиться с возможностью того, что любой поток может инициировать инициализацию объекта. Большинство реализаций singleton позволяют нескольким потокам одновременно обращаться к singleton с помощью метода «get reference», поэтому не адресуйте никаких проблем синхронизации, возникающих при использовании самого объекта. Я не вижу сильной причины, почему одноэлементный класс является Лучшее решение. –

1

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

4

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

0

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

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

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

+0

Плохая идея, которая плохо реализована. –

0

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

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

1

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

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

:: variable-name; 

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

0

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

1

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

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

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

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

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