263

コンパイラで typedef の前方宣言が許可されないのはなぜですか?

不可能だと仮定すると、包含ツリーを小さく保つためのベスト プラクティスは何ですか?

4

10 に答える 10

51

typedefを使用して定義されたCスタイルの構造体を前方宣言することを楽しみにしている私のような人のために、いくつかのc ++コードで、次のような解決策を見つけました...

// a.h
 typedef struct _bah {
    int a;
    int b;
 } bah;

// b.h
 struct _bah;
 typedef _bah bah;

 class foo {
   foo(bah * b);
   foo(bah b);
   bah * mBah;
 };

// b.cpp
 #include "b.h"
 #include "a.h"

 foo::foo(bah * b) {
   mBah = b;
 }

 foo::foo(bah b) {
   mBah = &b;
 }
于 2010-01-19T18:06:37.263 に答える
33

「fwddeclaretypedef」を実行するには、クラスまたは構造体をfwd宣言する必要があります。その後、typedefで宣言されたtypeを宣言できます。コンパイラでは、複数の同一のtypedefを使用できます。

長い形式:

class MyClass;
typedef MyClass myclass_t;

ショートフォーム:

typedef class MyClass myclass_t;
于 2011-08-05T02:01:02.477 に答える
17

C++ (プレーンな C ではない) では、両方の定義が完全に同一である限り、型を 2 回 typedef することは完全に合法です。

// foo.h
struct A{};
typedef A *PA;

// bar.h
struct A;  // forward declare A
typedef A *PA;
void func(PA x);

// baz.cc
#include "bar.h"
#include "foo.h"
// We've now included the definition for PA twice, but it's ok since they're the same
...
A x;
func(&x);
于 2009-04-30T01:04:10.920 に答える
9

型を宣言するには、そのサイズを知る必要があるためです。型へのポインターを前方宣言するか、型へのポインターを typedef できます。

本当にしたい場合は、pimpl イディオムを使用してインクルードを抑えることができます。ただし、ポインターではなく型を使用する場合、コンパイラーはそのサイズを認識している必要があります。

編集: j_random_hacker は、この回答に重要な条件を追加します。基本的には、型を使用するにはサイズを知る必要がありますが、型が存在することだけを知る必要がある場合は、ポインタまたは参照を作成するために前方宣言を行うことができます。タイプ。OPはコードを表示しませんでしたが、コンパイルできないと不平を言ったので、OPがタイプを参照するだけでなく、タイプを使用しようとしていると(おそらく正しく)想定しました。

于 2009-04-30T00:25:24.990 に答える
8

完全なs の代わりに前方宣言を使用できるのは、(このファイルのスコープ内で) 型自体を使用するのではなく、型へのポインターまたは参照を使用するつもり #includeがある場合のみです。

型自体を使用するには、コンパイラはそのサイズを認識している必要があります。したがって、その完全な宣言が表示される必要があります。したがって、完全な宣言#includeが必要です。

ただし、ポインターまたは参照のサイズは、ポインターのサイズに関係なくコンパイラーに認識されるため、型識別子名を宣言する前方宣言で十分です。

興味深いことに、classまたはstruct型へのポインターまたは参照を使用する場合、コンパイラーは不完全な型を処理できるため、指す型も前方宣言する必要がなくなります。

// header.h

// Look Ma! No forward declarations!
typedef class A* APtr; // class A is an incomplete type - no fwd. decl. anywhere
typedef class A& ARef;

typedef struct B* BPtr; // struct B is an incomplete type - no fwd. decl. anywhere
typedef struct B& BRef;

// Using the name without the class/struct specifier requires fwd. decl. the type itself.    
class C;         // fwd. decl. type
typedef C* CPtr; // no class/struct specifier 
typedef C& CRef; // no class/struct specifier 

struct D;        // fwd. decl. type
typedef D* DPtr; // no class/struct specifier 
typedef D& DRef; // no class/struct specifier 
于 2014-01-02T10:34:12.353 に答える