Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/161.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 静态成员函数与线程安全_C++_Multithreading_Static_Member Functions - Fatal编程技术网

C++ 静态成员函数与线程安全

C++ 静态成员函数与线程安全,c++,multithreading,static,member-functions,C++,Multithreading,Static,Member Functions,在静态成员函数中创建的对象和变量不像在成员函数中那样被认为是“本地”的,因此它们现在可以在多个线程之间共享,对吗 然而,如果您有一个创建某个对象的成员函数,那么它将是线程的本地对象,因此它是非共享的 我这样说对吗?函数是否是静态的并不重要(类方法)。只有自动变量才可视为函数的局部变量。如果您有这些数据的地址,您可以访问它 您可以使用,例如,将输出分配给专用线程上下文。不,您不正确。是的,C++非常滥用“静态”这个词。 静态类成员变量当然是一个全局变量,该类充当命名空间作用域,如果它是私有的或受保

在静态成员函数中创建的对象和变量不像在成员函数中那样被认为是“本地”的,因此它们现在可以在多个线程之间共享,对吗

然而,如果您有一个创建某个对象的成员函数,那么它将是线程的本地对象,因此它是非共享的


我这样说对吗?

函数是否是静态的并不重要(类方法)。只有自动变量才可视为函数的局部变量。如果您有这些数据的地址,您可以访问它


您可以使用,例如,将输出分配给专用线程上下文。

不,您不正确。是的,C++非常滥用“静态”这个词。 静态类成员变量当然是一个全局变量,该类充当命名空间作用域,如果它是私有的或受保护的(只能由类访问),则具有一些访问权限差异

然而,静态类成员函数就像常规自由函数(不是类成员),每次调用它时都有自己的局部变量

除了命名约定之外,静态类成员函数和常规自由函数之间唯一的真正区别在于,它可以访问类的私有成员(并且需要一个类的外部“实例”)

此外,可以从带有可变模板参数的模板调用静态类成员函数,调用通常称为“编译时多态性”的函数,该函数通常用于元编程


任何函数中的静态“局部”变量都是单个实例,另一方面,它也有点像全局变量,并且对线程争用问题很敏感,因为调用该函数的两个线程访问同一实例。

不,您的说法不正确

在静态函数中创建的对象不会共享,任何正常函数也是如此

如果对象本身声明为静态,则可以共享对象,这并不取决于函数是否为静态

void myFunc()
{
    static MyObject o;
    o.CallMethod(); // here o is shared by all threads calling myFunc
}
当一个对象被声明为静态时,就好像该对象是一个全局变量,但只在它声明到的函数范围内可见。

考虑这个类

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()

c
是一个实例变量;它附加到CData的特定实例化
func()
无法访问
c
,除非我在下面展示一个技巧

d
是一个静态变量。有一个
d
实例在所有CData类用户之间共享,因此可能需要同步。它可以从静态函数
func()
轻松使用

从静态函数访问实例数据的技巧是将有效对象传递到函数中

e、 g


希望有帮助。

创建对象至少有3种方法。X;X*X=新的X;X*X=new(mem)X.@Maxim,它们只能通过以下方式共享:
static X;静态X*X=新X你的评论是什么意思/暗示?很模糊!?这是:X*X=新(mem)X;可以创建线程或进程之间共享的对象。它可以从静态成员函数中完成,这证明您的语句“在静态函数中创建的对象不共享”是错误的。@Maxim,我没有使用
X*X=new(mem)X
但是
X*X=new X可能存在同样的问题。。。然而,在这种情况下,它并不取决于静态函数和非静态函数之间的区别,这正是初学者在这个问题中所要求的。@Maxim:“在静态函数中创建的对象”仅指本地/自动对象。例如,void f(){int local_var;}。我理解你的困惑,但我很清楚——我想,大多数人也很清楚——这是什么意思(尽管应该在教学等方面详细说明)。托尼的可能翻版,到底为什么你又问同样的问题?@Suma我投票结束了我自己的问题,忘了我已经问过这个问题了…哈哈,没有意识到这个问题的副本也有相同的OP。可能的副本是我见过的最好的解释。非常感谢。帮了我很多忙!干净利落!我遇到的最好的解释,切中要害,非常感谢!
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);
}