2016-08-25 12 views
1

私はお互いにやりとりするクラスがたくさんあるプロジェクトで働いているので、.cppファイルだけを含めたいと思っています。あなたがすでに含まれているかどうかを心配する必要がないので、私はちょうどそれを行う方法をよく知らない。 はここに例を示しますちょうどcppファイルに含まれていること

#include "UnitConverter.hpp" 
#include <string> 
//extern namespace std; 
//extern class std::string; 
//extern class UnitConverter; 
//extern enum UnitConverter::UnitTypes; 
//extern enum UnitConverter::UnitSystem; 
//extern enum UnitConverter::ScalingType; 

class AnalogOutput{ 

    public: 
    std::string name; 
    UnitConverter::UnitTypes unit_type; 
    UnitConverter::UnitSystem unit_system; 
    UnitConverter::ScalingType scaling_type; 
} 

ことがHPPファイルではなく、CPPファイルに含まれずにコンパイルので、私は名前空間、クラスや列挙型を宣言するだろうか?

+3

私はなぜそれをしたいのですか? –

+4

なぜあなたは「あなたがすでに含まれているかどうか」を心配していますか?あなたが必要とするものを含めるだけです。同じヘッダーを2度入れると、ガードが含まれているものがうまくいきます。 – user463035818

+1

代わりにすべてを宣言し、ポインタと参照のみを使用することもできます。しかし、各クラスに独自のヘッダーを持つソートされたインクルードシステムを使用すると、より明確に見え、頭痛が軽減されます。その後、使用していないインクルードがあるかどうかを確認するために、いくつかのツールを使用することもできます。 – Hayt

答えて

2

std::stringすると、あなたのためにそれが困難になります...より良いは、1つの心配はありません - あなたが円形になるだろうということは極めてまれであるシステムヘッダに含まれています...彼らはそれに対応するヘッダーで宣言されているとして、プロジェクトのクラスの場合

、あなたは正確にそれらを宣言する必要があります。

// Example.h 
namespace Dummy 
{ 
    class Example { /* ... */ }; 
} 

をそして避けるためには含まれています

// Test.h 
namespace Dummy 
{ 
    class Example; // just the bare name! 
} 

しかし、この方法では不完全な型を取得し、直接使用することはできません。ポインタや参照を使用することはできますが、次のような構図はうまくいかないでしょう:

// Test.h 
/* ... */ 
class Test 
{ 
    Dummy::Example ex; // type is incomplete! 
    Dummy::Example& ex_r; // reference is OK 
    Dummy::Example* ex_p; // pointer, too 

    inline void foo() 
    { 
     // type incomplete; you cannot do this here: 
     ex_p->bar(); 
     // needs to be done in cpp file where Example.h is included instead 
    } 
}; 
+0

Upvoteは 'std :: string'を宣言するのが難しいです - 私は自分自身のことを考えませんでした... :) – atkins

+0

@atkins一緒に共通の答えを書いているはずです... – Aconcagua

+0

うーん、ありがとうたくさんの男、私はhppファイルに必要なものを残して、ちょうど注意すると思います。 @atkins – heczaco

6

これは、必要なすべてが含まれているすべての場所に含めるヘッダーを使用して実現できます。

catch-allヘッダーを使用するとコンパイル時間が短縮されます。ひどく。しないでください。行う。それ。

2

forward declarationsを使用しているようです。これを行うには、構文はclass MyClass;です(接頭辞externは必要ありません)。

と名前空間であなたの前方宣言をラップ、名前空間に存在するクラスを宣言転送する:

namespace MyNamespace { 
    class MyClass; 
} 

はしかし、あなたのコードスニペットに関連し、ここで、少なくとも二つの大きな注意点があります

  1. ポインタまたは参照は、 の宣言された型に対してのみ使用できます。したがって、あなたの例では、std::stringの宣言を転送することができません。AnalogOutputクラスにstd::stringのメンバーがいれば、代わりにそのメンバーをポインタまたは参照に変更する必要があります。
  2. You can't forward declare nested types。したがって、enumsはすべてUnitConverterにネストされているため、これを宣言することはできません。それは、テンプレートへのtypedefであるよう
+0

入れ子型のupvote - 私は自分自身のことを考えていませんでした... – Aconcagua

関連する問題