Подтвердить что ты не робот

Статические функции элементов и безопасность потока

Объекты и переменные, созданные в статической функции-члене, не считаются "локальными", как в функции-члене, так что теперь они могут быть разделены между несколькими потоками правильно?

Если у вас есть функция-член, которая создает какой-то объект, это будет локально для потока и, следовательно, не является общим.

Правильно ли я это говорю?

4b9b3361

Ответ 1

Нет, вы не правы.

Объекты, созданные в статической функции , не являются совместно, и это также относится к любым нормальным функциям.

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

void myFunc()
{
    static MyObject o;
    o.CallMethod(); // here o is shared by all threads calling myFunc
}

Когда объект объявляется статическим, он выглядит так, как если бы объект был глобальной переменной, но был видимым только в области функции, в которую он был объявлен.

Ответ 2

Рассмотрим этот класс

class CData
{
public:
    static void func()
    {
        int a;
        static int b;
    }

    int c;
    static int d;
};

int main()
{
    CData::func();
}

Теперь переменная a является локальной для каждого вызова func(). Если два потока одновременно называют func(), они получают разные версии a.

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

c - переменная экземпляра; он привязан к конкретному экземпляру CData. func() не может получить доступ к c, за исключением трюка, который я покажу ниже.

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

Трюк, используемый для доступа к данным экземпляра из статической функции, заключается в передаче действительного объекта в функцию.

например.

class CData
{
public:
    static void func(CData *p)
    {
        int a;
        static int b;

        b = p->c;
    }

    int c;
    static int d;
};

int main()
{
    CData data;
    CData::func(&data);
}

Надеюсь, что это поможет.

Ответ 3

Нет, вы не правы. И да, С++ очень сильно злоупотребляет словом "статический".

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

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

Единственное реальное различие между функцией статического члена класса и регулярной бесплатной функцией, кроме соглашения об именовании, заключается в том, что он имеет доступ к закрытым членам класса (и для этого нужен внешний "экземпляр" ).

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

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

Ответ 4

Не имеет значения, является ли функция статической или нет (метод класса). Только автоматические переменные можно рассматривать как локальные функции. Если у вас есть адрес этих данных, вы можете получить к нему доступ.

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