Удивительно, что тип 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)
Объявите это в одном заголовочном файле (использование 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
вероятно, имеет что-то для этого.
Лучший совет, вероятно, "стараются избегать globals". Людям не нужны глобальные переменные так часто, как они думают. Обычно оказывается, что "передача всего как аргументы конструкторам" не является вполне такой работой, как люди думают, когда они слышат предложение. Это также имеет тенденцию приводить к более чистому коду с меньше, и более явный, зависимости.
Я не знаю ни о каком "корректном" способе объявить globals в C++. Путем Вы делаете это, теперь хорошо работает, но порядок инициализации является неуказанным, поэтому если существуют какие-либо зависимости между Вашим globals, Вы в беде.
Функция, возвращая статический экземпляр более или менее решает ту проблему, но не ориентирована на многопотоковое исполнение.
И одиночный элемент является просто ужасной идеей. Это не решает Вашу проблему, но добавляет дополнительные ограничения к Вашему коду, которые не были на самом деле необходимы, и скорее всего возвратятся и укусят Вас позже.
Объявите как экстерн в одном заголовочном файле, включенном "многими", и определите его в одном *.cpp файле
Ваша идея статической внутренней части функция средства доступа существенно отличается от глобальной переменной. Различие - когда оно создается и, скорее всего, будет основной проблемой с несколькими потоками. Что, если два потока звонят MyGlobalClassInstance
одновременно? В зависимости от среды, но я подозреваю, что это типично для большинства компиляторов C++, Вы потенциально получите два вызова конструктору MyGlobalClass
выполнение одновременно, обращение к той же области памяти.
Если Вы будете однопоточными, то это, менее вероятно, будет проблема.
Если Вы объявите экземпляр как нормальный статический участник или как нормальная глобальная переменная в исходном файле, то у Вас, вероятно, будет более легкое время, потому что конструктора вызовут прежде main
выполняется, прежде чем у Вас будет шанс запустить другие потоки.
объявите и определите в cpp файле
Сохраните extern
- объявление редактора в заголовке. Определите его только однажды в файле реализации.
Вы близки. Используйте пространство имен вместо этого для глобальных переменных.
namespace myns {
int foo = 0;
}
Теперь, если это - объект класса, Вы смотрите на шаблон Singletion. На самом деле Ваш пример кода отражает дизайн Singleton. Однако, если Вы собираетесь определить функцию в заголовке, заставьте его встроить - нарушение ODR иначе.
Почему бы не использовать старый добрый шаблон "одиночка"?
Он это - действительно глобальная переменная, к которой мог теоретически получить доступ внешне любой модуль, необходимо поместить объявление экстерна в заголовочный файл:
// 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
экстерн MyGlobalClass MyGlobalClassInstance;
Править: Не статичный>. <