答えて
型を宣言するために、そのサイズを知る必要があります。型へのポインタを宣言したり、型へのポインタをtypedefしたりすることができます。
本当にしたい場合は、pimplイディオムを使用してインクルードを下げておくことができます。しかし、ポインタではなくタイプを使用したい場合、コンパイラはそのサイズを知る必要があります。
編集:j_random_hackerはサイズが使用タイプに知ることが必要である基本的にことを、この回答への重要な資格が追加されますが、我々は唯一のが存在するタイプを知っておく必要がある場合は前方宣言をして、行うことができますその型へのポインタまたは参照を作成します。 OPはコードを示していないが、コンパイルしないと訴えていたので、私はOPがを使用しようとしていたと仮定しただけではなく、というタイプを使用していました。
正式なtypedefを行うことができます。しかし
typedef A B;
を行うには、まず、前方A
を宣言しなければなりません:C++(ただし、プレーンC)では
class A;
typedef A B;
を、それはとても長い間、両方の定義が完全にあるとして、二度タイプをtypedefのために完全に合法です同じ:typedeを使用して定義されたCスタイルの構造体を宣言転送するために探している人、私のようなあなたのそれらについては、
// 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);
メンテナンスいいえいいえ、この種のことは、飼い主の中で遅かれ早かれあなたを噛むでしょう。 –
@MarkStorer、少なくともコンパイラはどんな違いも捕らえてエラーを生成します。私はこれをVisual C++で検証しました。 – Alan
いいですが、 'A'が定義によって空であるので、この方法で' A'フィールドをどのように定義しますか? –
fは、いくつかのC++のコードでは、私はあなたがFWDクラスまたは構造体を宣言した後、あなたが宣言された型をtypedefをすることができます必要な「FWDのtypedefを宣言」するには...
// 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;
}
+1のプラグマティズム – Travis
@LittleJohnこの解決策の問題は、ダミー名_bahがパブリックAPIの一部と見なされないことです。 forward delcare FILEを参照してください。 – user877329
を次のようになります解決策を発見しました。複数の同一のtypedefがコンパイラによって受け入れられます。
長い形式:
class MyClass;
typedef MyClass myclass_t;
短い形式:あなたは型自体を使用して意図ないをしているときにのみ
typedef class MyClass myclass_t;
前方宣言を使用したフル#include
秒の代わりにが可能です(このファイルの有効範囲内)ではなく、ポインタまたはその参照です。
型自体を使用するには、コンパイラはそのサイズを知っている必要があります。そのため、完全な宣言が必要です。したがって、完全な#include
が必要です。
ただし、ポインタまたは参照のサイズは、pointeeのサイズに関係なくコンパイラに認識されます。したがって、前方宣言で十分です。型識別子の名前が宣言されています。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
を私は同じ問題を持っていました、異なるファイル内に複数のtypedefを台無しにしたくなかったので、私は、継承とそれを解決:
されました:
class BurstBoss {
public:
typedef std::pair<Ogre::ParticleSystem*, bool> ParticleSystem; // removed this with...
ました:
class ParticleSystem : public std::pair<Ogre::ParticleSystem*, bool>
{
public:
ParticleSystem(Ogre::ParticleSystem* system, bool enabled) : std::pair<Ogre::ParticleSystem*, bool>(system, enabled) {
};
};
を魅力のように働きました。もちろん、私は
BurstBoss::ParticleSystem
単に
ParticleSystem
からすべての参照を変更しなければならなかったビルKotsiasが指摘したように、プライベートあなたのポイントのtypedefの詳細を維持し、前方にそれらを宣言するための唯一の合理的な方法であります継承あり。あなたはC++ 11でこれをもっとうまくいくことができます。
// LibraryPublicHeader.h
class Implementation;
class Library
{
...
private:
Implementation* impl;
};
// LibraryPrivateImplementation.cpp
// This annoyingly does not work:
//
// typedef std::shared_ptr<Foo> Implementation;
// However this does, and is almost as good.
class Implementation : public std::shared_ptr<Foo>
{
public:
// C++11 allows us to easily copy all the constructors.
using shared_ptr::shared_ptr;
};
まあ、クラス型の前方宣言は、そのサイズの知識がなくても、これらのタイプを宣言します。これを考慮してください。また、ポインタとそのような不完全な型への参照を定義できることに加えて、パラメータを取る、および/またはそのような型の値を返す関数を宣言することはできますが、定義することはできません。 –
申し訳ありませんが、私はそれが良い前提だとは思いません。この回答は、ポイントの横にあります。これは、前方宣言のtypedefの場合と非常によく似ています。 – Cookie