class A {
public:
A();
private:
pthread_mutex_t mu;
};
A::A()
{
mu = PTHREAD_MUTEX_INITIALIZER; //cannot compile
}
pthread_mutex_t
クラスメンバー関数内で初期化できませんか?
これの代わりに:
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構造体初期化子であり、定義の時点でのみ使用できます。
pthread_mutex_init
定数はコンパイル時の初期化用であるため、この場合に使用します。
コンストラクターで初期化子リストを使用するようにこれを変更しても、失敗します。
#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
}
@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()
、メンバー関数内で(他の人が示したように)関数を使用します。