コンパイラで typedef の前方宣言が許可されないのはなぜですか?
不可能だと仮定すると、包含ツリーを小さく保つためのベスト プラクティスは何ですか?
コンパイラで typedef の前方宣言が許可されないのはなぜですか?
不可能だと仮定すると、包含ツリーを小さく保つためのベスト プラクティスは何ですか?
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;
}
「fwddeclaretypedef」を実行するには、クラスまたは構造体をfwd宣言する必要があります。その後、typedefで宣言されたtypeを宣言できます。コンパイラでは、複数の同一のtypedefを使用できます。
長い形式:
class MyClass;
typedef MyClass myclass_t;
ショートフォーム:
typedef class MyClass myclass_t;
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);
型を宣言するには、そのサイズを知る必要があるためです。型へのポインターを前方宣言するか、型へのポインターを typedef できます。
本当にしたい場合は、pimpl イディオムを使用してインクルードを抑えることができます。ただし、ポインターではなく型を使用する場合、コンパイラーはそのサイズを認識している必要があります。
編集: j_random_hacker は、この回答に重要な条件を追加します。基本的には、型を使用するにはサイズを知る必要がありますが、型が存在することだけを知る必要がある場合は、ポインタまたは参照を作成するために前方宣言を行うことができます。タイプ。OPはコードを表示しませんでしたが、コンパイルできないと不平を言ったので、OPがタイプを参照するだけでなく、タイプを使用しようとしていると(おそらく正しく)想定しました。
完全な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