1

この質問に似たものを見つけるのに苦労しているので、代わりにここで質問します。

ダースほどのソース/ヘッダー ファイルを含むプロジェクトがあります。私が抱えている主な問題は、名前空間で作成したクラスを事前定義することです。コードは次のとおりです。

「GlobalIncludes.h」

/*include dependencies and library headers...*/

/*[Note 1]How would I predefine the classes inside namespaces?*/

typedef std::tr1::shared_ptr<Class1> ClassPtr1;//[Note 2]
typedef std::tr1::shared_ptr<Class2> ClassPtr2;//[Note 2]

/*[Note 2]What is the correct way to predefine the shared_ptr's?*/

#include "Class1.h"
#include "Class2.h"

「Class1.h」

namespace myNamespace
{
    class Class1
    {
        /*variables and functions*/
        void doSomething(...);
        Class2 exampleObject;
    };
}

「Class2.h」

namespace myNamespace
{
    class Class2
    {
        /*variables and functions*/
    };
}

これが少し混乱を招くように聞こえる場合は、事前にお詫び申し上げます... 基本的に、クラスを事前定義namespace myNamespaceし、同時に を宣言することが可能かどうか疑問に思っていshared_ptrます。これが可能である場合、どうすればこれを行い、ソースで正しく使用できますか?

4

2 に答える 2

6

型定義をクラスと同じ名前空間の一部にしたい場合 (これをお勧めします):

namespace my_namespace
{
    class Class1;
    class Class2;

    typedef std::tr1::shared_ptr<Class1> ClassPtr1;
    typedef std::tr1::shared_ptr<Class2> ClassPtr2;
}

#include "Class1.h"
#include "Class2.h"    

それ以外の場合、ポインター型の定義をグローバル名前空間の一部にしたい場合

namespace my_namespace
{
    class Class1;
    class Class2;
}

typedef std::tr1::shared_ptr<my_namespace::Class1> ClassPtr1;
typedef std::tr1::shared_ptr<my_namespace::Class2> ClassPtr2;

#include "Class1.h"
#include "Class2.h"    

おそらく、マクロを使用して物事をよりコンパクトにすることができます(同じ名前空間):

#define DECLARE_PTR_ALIAS(N, C, P) \
    namespace N { class C; 
    typedef std::tr1::shared_ptr<C> P; } \

または (別の名前空間):

#define DECLARE_PTR_ALIAS(N, C, P) \
    namespace N { class C; } \
    typedef std::tr1::shared_ptr<N::C> P;

これにより、いくつかのクラスのポインター エイリアスを簡単に定義できます。

DECLARE_PTR_ALIAS(my_namespace, Class1, ClassPtr1)
DECLARE_PTR_ALIAS(my_namespace, Class2, ClassPtr2)
...
于 2013-02-28T18:07:55.767 に答える
0

名前空間でクラス (または関数など) を事前に宣言するには、次のようにします。

namespace myNamespace
{
    class myClassA;
    class myClassB;
}

単一のクラスを事前に宣言するだけの場合は、1 行に入れるのが好きです: (個人的な好み)

namespace myNamespace { class myClassA; }

ただし、あなたの例では、 Class1 は既に名前空間にあるため、次のようにすることもできます。

namespace myNamespace
{
    class Class2;

    class Class1
    {
        /*variables and functions*/
        void doSomething(...);
        Class2 exampleObject;
    };
}

唯一の問題は、Class1 が Class2 をメンバー変数として持つことです。コンパイラはオブジェクトをクラスに埋め込むためにオブジェクトのサイズを知る必要があるため、事前に宣言されたオブジェクトをメンバーとして使用することはできません。事前に宣言されたオブジェクトは、サイズが固定されているため、参照またはポインターとしてのみ使用できます。

Class2 をスマート ポインターにした場合は、次のようにできます。

namespace myNamespace
{
    class Class2;

    typedef std::shared_ptr<Class2> Class2ptr;

    class Class1
    {
        /*variables and functions*/
        void doSomething(...);
        Class2ptr exampleObject;
    };
}

ただし、shared_ptr は完全に含まれている必要があり、事前に宣言することはできません。これは、shared_ptrs がメンバー変数になり、クラスが完全なサイズを知る必要があるためです

于 2013-02-28T18:36:11.320 に答える