Открыть список
Как стать автором
Обновить

Комментарии 22

Самое главное (для начинающих) про порядок инициализации не рассказали.
Мне кажется, что сегменты — это уже platform-specific?

Точнее, о беспорядке инициализации, известном как «initialization order fiasco»)

Про инициализацию статической переменной в функции и многопоточность не рассказали.

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

В c++11 и выше статические переменные создаются один раз на все потоки. Это может вызывать проблему, так как такое создание по сути обернуто в мьютекс, что может вызывать падение производительности
Не совсем так. Если инициализация разрешима на этапе компиляции, то статическая переменная инициализируется вместе с определенными глобалками, а вот если на определена, то да, появляется флаг защиты. Особенно смешно, когда переменная типа байт защищается при помощи бита в слове.

Вообще то, на мой взгляд, применение слово static в плюсах совершенно очевидным образом перегружено, причем весьма далекими по значению смыслами.
>> Как известно, мы не можем определить функцию в заголовочном файле не сделав ее inline или static… Это решает проблему, но влечет за собой увеличение размера выполняемого файла, т.к. директива include просто копирует содержимое заголовочного файла в .cpp файл.

inline определит только один экземпляр функции, в то время как static для каждого включения будет иметь свою локальную статическую переменную в функции

Я еще периодически стреляю себе в ногу, когда делаю статическую переменную внутри метода, а потом оказывается, что она общая для всех объектов такого класса -_-'

Интересно, зачем ещё делать static переменную внутри метода? В чём оказия?

Да как и в функции, в принципе — чтобы состояние сохранить до следующего вызова. Только тут надо бы в объект поле добавить, а что-то лень, сделаю просто static...

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

Добавил бы, что static методы в классе не имеют скрытый параметр this, который всегда есть у обычных методов.
Статическая глобальная переменная и статическая глобальная функция…
Пример со статическим членом класса без его определения в cpp файле не слинкуется. А еще вы забыли про статические переменные вне функций, видимые в пределах файла.
Пример со статическим членом класса без его определения в cpp файле не слинкуется.

Слинкуется. Никаких проблем в этом плане не будет, пока этот статический член не ODR-used (очевидно, что в примере B::a не ODR-used).

Начиная с С++17 есть еще одна замечательная вещь: inline static data member. Позволяет писать header-only библиотеки без всяких трюков.
Пример:


//file.h
struct A {
    inline static int a;
};  

A::a здесь полностью определена без необходимости в cpp файле.

Всем привет. В ближайшее время, я детально разберу каждый комментарий и добавлю ваши отличные предложения! Огромное спасибо, что помогаете сделать статью лучше.
«область видимости count будет до конца функции main()» static не меняет область видимости, он влияет на время жизни переменной.
Потерялись статические глобальные переменные, ситуация с которыми точно такая же, как с функциями.

Ну и если смешивать в рассказе о static все его области применения, то имеет смысл до кучи добавить и простые глобальные переменные, которые тоже располагаются в статической памяти, заодно есть повод рассказать о порядке вызова их конструкторов.
Ещё бы почитать про влияние static на шаблоны и лямбда ф-ии.
Спасибо. Компактная но полезная статья.
Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.