Что лучший способ состоит в том, чтобы объявить глобальную переменную?

Удивительно, что тип System.Version не поддерживает методы приращения компонентов номера версии (как и тип PowerShell Core-only System.Management.Automation.SemanticVersion ). ). [1 110]

Вот решение PSv5 +:

$versionString = '1.2.0'

$version = [version] $versionString

$versionStringIncremented = [string] [version]::new(
  $version.Major,
  $version.Minor,
  $version.Build + 1
)

# $versionStringIncremented now contains '1.2.1'

Если вы хотите обернуть это в функцию , которая позволяет увеличивать любой из компонентов , в то же время устанавливая все нижние компоненты на 0 или, в случае .Revision, до неопределенного (сообщается как -1):

function Increment-Version {
  param(
    [Parameter(Mandatory)]
    [version] $Version
    ,
    [ValidateSet('Major', 'Minor', 'Build', 'Revision')]
    [string] $Component = 'Revision'
  )

  $useRevision = $Version.Revision -ne -1 -or $Component -eq 'Revision'

  $Major, $Minor, $Build, $Revision =
    $Version.Major, $Version.Minor, $Version.Build, $Version.Revision

  switch ($Component) {
    'Major' { $Minor = $Build = 0 }
    'Minor' { $Build = 0 }
  }

  Set-Variable $Component (1 + (Get-Variable -ValueOnly $Component))

  if ($useRevision) {
    [version]::new(
      $Major,
      $Minor,
      $Build,
      $Revision
    )
  } else {
    [version]::new(
      $Major,
      $Minor,
      $Build
    )
  }

}

Ваша команда затем упростится до:

# -> '1.2.1'
$versionStringIncremented = [string] (Increment-Version 1.2.0 -Component Build)

# -> '1.3.0'
$versionStringIncremented = [string] (Increment-Version 1.2.7 -Component Minor)

5
задан GEOCHET 13 March 2009 в 15:38
поделиться

8 ответов

Объявите это в одном заголовочном файле (использование extern), и определите его в одном .cpp (или безотносительно другого расширения) файл. Можно использовать функцию и возвратиться, ссылка на статическую переменную как Вы показала для хитрости проблем с порядком конструкции относительно других таких переменных объема пространства имен в другом .cpp файлы. Но помните, что это не защитит Вас от проблем порядка разрушения - который находится в точном обратном порядке от конструкции (эти вещи называют "статическим фиаско порядка инициализации". Если Вы используете функцию как Ваша и помещаете ее в заголовки, заставьте ее встроить для создания переопределения из функции допустимым, когда она включена в несколько .cpp файлы (логически, функция все еще только очевидна однажды, потому что помехи в ней будут только существовать однажды, не отдельно для каждого файла, она включена в). Кроме того, просто объявите это в заголовке, но определите его в одном .cpp файл (но затем, удалите встроенное из него!).

inline A& getA() { static A a; return a; }

Потенциальные проблемы с порядком разрушения могут обойтись при помощи new:

inline A& getA() { static A *a = new A; return *a; }

Деструктор его, однако, никогда не будут называть затем. При необходимости в потокобезопасности необходимо добавить взаимное исключение, которое защищает от множественных доступов. boost.thread вероятно, имеет что-то для этого.

2
ответ дан 18 December 2019 в 08:31
поделиться

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

Я не знаю ни о каком "корректном" способе объявить globals в C++. Путем Вы делаете это, теперь хорошо работает, но порядок инициализации является неуказанным, поэтому если существуют какие-либо зависимости между Вашим globals, Вы в беде.

Функция, возвращая статический экземпляр более или менее решает ту проблему, но не ориентирована на многопотоковое исполнение.

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

10
ответ дан 18 December 2019 в 08:31
поделиться

Объявите как экстерн в одном заголовочном файле, включенном "многими", и определите его в одном *.cpp файле

4
ответ дан 18 December 2019 в 08:31
поделиться

Ваша идея статической внутренней части функция средства доступа существенно отличается от глобальной переменной. Различие - когда оно создается и, скорее всего, будет основной проблемой с несколькими потоками. Что, если два потока звонят MyGlobalClassInstance одновременно? В зависимости от среды, но я подозреваю, что это типично для большинства компиляторов C++, Вы потенциально получите два вызова конструктору MyGlobalClass выполнение одновременно, обращение к той же области памяти.

Если Вы будете однопоточными, то это, менее вероятно, будет проблема.

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

2
ответ дан 18 December 2019 в 08:31
поделиться

объявите и определите в cpp файле

Сохраните extern- объявление редактора в заголовке. Определите его только однажды в файле реализации.

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

namespace myns {
   int foo = 0;
}

Теперь, если это - объект класса, Вы смотрите на шаблон Singletion. На самом деле Ваш пример кода отражает дизайн Singleton. Однако, если Вы собираетесь определить функцию в заголовке, заставьте его встроить - нарушение ODR иначе.

1
ответ дан 18 December 2019 в 08:31
поделиться

Почему бы не использовать старый добрый шаблон "одиночка"?

-1
ответ дан 18 December 2019 в 08:31
поделиться

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

// MyClass.h
class MyClass { ... };
extern MyClass myGlobalInstance;

// MyClass.cpp
MyClass myGlobalInstance;

Если это - просто глобальный объект, к которому должен действительно только получить доступ единственный модуль, ограничить его объем или созданием его частное (или защищенный) статическая переменная класса, статическая функциональная переменная (если это только необходимо одной функции), или в анонимном пространстве имен:

Опция 1:

// MyClass.h
class MyClass
{
private:  // or protected, if you want it accessible by subclasses
    static MyClass myGlobalInstance;
};

Опция 2:

// MyClass.cpp
void someFunction()
{
    // it's global, but only accessible inside this function
    static MyClass myGlobalInstance;
    ...
}

Опция 3:

// MyClass.cpp
namespace
{
    MyClass myGlobalInstance;
}

// it's now only accessible in this file
1
ответ дан 18 December 2019 в 08:31
поделиться

экстерн MyGlobalClass MyGlobalClassInstance;

Править: Не статичный>. <

0
ответ дан 18 December 2019 в 08:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: