- ベストアンサー
【C++】typedefの役割について
C++だけでなく、Cでも同様なのだと思うのですが、下記の(1)、(2)の違い がよくわからず、どなたかにご教授いただければと思っています。 (1) struct{ (略) }BBB; (2) typedef struct{ (略) }BBB; (2)が下記((2)')のようになるんであれば、AAAという名前の構造体を BBBという名前で定義しているという事で理解できるんですが、 (2)のようにしている意図が理解できません。 (typedefの記述は必要なんでしょうか?) すでに動いているシステムなので、問題ないのは明らかなんですが。 (2)' typedef struct AAA{ (略) }BBB;
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
> すみません。BBBとAAAの記述が反対で、 何か誤解があるようです。 typedef struct{ (略) }BBB; の型は struct { (略) } であり、 typedef struct BBB{ (略) }AAA; の型は struct BBB { (略) } です。 両者は別の型ですし、タグがAAAになってもそれは同じことです。 > ★これは、typedefの記述が無くても同様ではないんでしょうか?(下記(3)) typedefがなければ、それは型定義ではなくオブジェクトの宣言になります。 > typedefが必要なのかが理解できていません。 最初に書いたように、タグ名がない構造体は、たとえ内容が全く同じでも出現するたびに別の型になります。したがって、タグが無い場合にはtypedef名を定義しておかない限り、その型を再度指定する手段がなくなります。 (GCCのようにtypeof演算子がある場合や、C++でテンプレートを用いた場合は別です)
その他の回答 (3)
- venzou
- ベストアンサー率71% (311/435)
>typedefの役割について 質問の例はわかり難いので、例を変えて説明します。 ---------------------------------------------- //(a) struct { int hoge; } aaa; //(b) struct BBB{ int hoge; } bbb; //(c) typedef struct { int hoge; } ccc; //(d) typedef struct DDD{ int hoge; } ddd; void test1(void){ aaa.hoge = 10; bbb.hoge = 10; ccc.hoge = 10; // NG (1) ddd.hoge = 10; // NG (2) } void test2(void){ struct { int hoge; }aaa2; aaa2 = aaa; // NG (3) struct BBB bbb2; bbb = bbb2; ccc ccc1; ccc ccc2; ccc1 = ccc2; ddd ddd1; struct DDD ddd2; ddd1 = ddd2; } ---------------------------------------------- // NG の行はコンパイルエラーになると思いますが、 理由は分かりますか? (a)は変数の宣言。 (b)は型の宣言と、変数の宣言。 (c)は別名の宣言。 (d)は型の宣言と、別名の宣言。 test1() は、メンバへの代入を試みています。 NG (1) と (2) のエラーは、ccc dddは変数では無く、 型の別名ですので、そのまま変数の様には扱えません。 test2() は、同じ型の変数を用意して構造体の代入を試みています。 NG (3) は、aaa と同じように宣言していますが、 別の型として扱われるので、エラーになります。 また、下記の2行を比べてください。 同じ型の構造体の変数を宣言していますが、 typedefで定義した別名を使う方が、簡素になります。 ddd ddd1; struct DDD ddd2; typedefの主な用途はこの点だと思います。 #専門家ではないので、細かい専門用語の間違いなどはご容赦下さい。 #サンプルソースはレイアウトの為に全角スペースを入れています。
お礼
なるほど^^ 例まで書いていただき、ありがとうございます。 自分の理解が足りていない部分が回答内容から 良くわかりました。
- jacta
- ベストアンサー率26% (845/3158)
(2)と(2)'では型が異なります。 タグ名のない構造体は、内容が全く同じであっても、その定義が現れるたびに別の型であると認識されます。もちろん、内容が全く同じタグ名付きの構造体とは別の型です。 (2)では、その型を扱う場合には常にBBBという名前を使うことを意図しており、タグ名前空間を汚染していません。 それに対して、(2)'では、AAAという名前が、実際に使われるかどうかにかかわらず、タグ名前空間を汚染しています。 C++では若干事情が異なります。C++ではタグ名前空間というものがありません。したがって、使用しないタグ名を付けると、一般的な識別子とぶつかる可能性が出てきます。
お礼
回答ありがとうございます。 1つ質問を追加(下記★)させていただきましたので、 すみませんが、回答いただければうれしいです。 >(2)と(2)'では型が異なります。 そうですね^^; すみません。BBBとAAAの記述が反対で、 ------------------------------------------- typedef struct BBB{ (略) }AAA; BBBという名前の構造体をAAAという名前で定義 ------------------------------------------- ↑の誤りでした。失礼しました。 >(2)では、その型を扱う場合には常にBBBという名前を使うことを意図しており、タグ名前空間を汚染していません。 ★これは、typedefの記述が無くても同様ではないんでしょうか?(下記(3)) typedefが必要なのかが理解できていません。 (3) struct{ (略) }BBB;
- php504
- ベストアンサー率42% (926/2160)
2は2'の省略型 typedefで名前つけてるので構造体名を省略したのでしょう
お礼
早急な回答、ありがとうございました。
お礼
混乱してたようです^^; 再度の対応をいただき、ありがとうございます。 回答内容を良く整理して、これ以上混乱しないようにしたい と思っております。