6
class A {
    public:
        A();
    private:
        pthread_mutex_t mu;
};

A::A()
{
    mu = PTHREAD_MUTEX_INITIALIZER;  //cannot compile
}

我不能pthread_mutex_t在类成员函数中初始化吗?

4

4 回答 4

11

而不是这个:

A::A()
{
    mu = PTHREAD_MUTEX_INITIALIZER;  //cannot compile
}

尝试这个:

A::A()
{
pthread_mutex_init( &(mu), NULL);
}

PTHREAD_MUTEX_INITIALIZER 是一个宏,是一个用于 {0,0,0,0,0{0}} 之类的 C 结构初始化程序,只能在定义点使用。

于 2012-07-26T10:03:34.160 回答
8

在这种情况下使用pthread_mutex_init,因为常量用于编译时初始化。

于 2012-07-26T09:53:20.517 回答
2

即使我们将其更改为在构造函数中使用初始化列表,它仍然会失败:

#include <pthread.h>

struct foo {
  pthread_mutex_t test;
  foo() : test(PTHREAD_MUTEX_INITIALIZER) {}
};

int main() {
  foo f;
}

我们可以通过查看预处理器的输出来了解它为什么失败并且仅用于在少数情况下进行初始化:

struct foo {
  pthread_mutex_t test;
  foo() : test({ { 0, 0, 0, 0, 0, { 0 } } }) {}
};

在 C++03 中使用嵌套大括号进行初始化是不合法的,但更有趣的是 C++11 使这种语法和用法完全合法。

在您的原始代码中,我们可以看到更多内容:

A::A()
{
    const pthread_mutex_t test = PTHREAD_MUTEX_INITIALIZER; //  initialization - fine
    mu = test; // assignment - fine
    mu = PTHREAD_MUTEX_INITIALIZER;  // assignment - C++11 only
}
于 2012-07-26T10:04:58.193 回答
0

我喜欢@askmish 和@Diego 的答案。我也喜欢@Flexo 解释的内容。

但作为一种选择,如果您打算使用PTHREAD_MUTEX_INITIALIZER宏进行初始化,您可以做的是,在类定义中进行互斥体声明,static如下所示:

class A {
    public:
        A();
    private:
        static pthread_mutex_t mu;
};

然后您可以在源文件中初始化此静态互斥锁,但在任何成员函数之外,如下所示:

class A {
    public:
        A();
    private:
        static pthread_mutex_t mu;
};

pthread_mutex_t A::mu = PTHREAD_MUTEX_INITIALIZER;

A::A()
{
}

您的选择:

  • 因此,要么保持宏并保持静态(如此处所示)。或者,
  • 您保持互斥锁的声明相同(非静态),但在pthread_mutex_init()成员函数中使用该函数(如其他人所指出的)。
于 2019-08-09T09:16:57.713 回答