2011-10-20 4 views
2

私のヘッダーで私は文字列を作った:string s;これでコンパイラが狂っている。私は文字列がiostream :: stdの一部であることを知っています。 .cppファイルの代わりにヘッダにインクルードする必要がありますか?そうであれば、ヘッダを使用する他のファイルにiostreamが含まれていると悪いですか?どのように私はそれに対処するのですか?ヘッダーの文字列プロトタイプにはiostreamが必要ですか?

編集:ベクターの場合は、私の割り当てに多くの必要があるように思われるので、

Edit2:ヘッダーの例の多くで#ifndefが表示されたことを覚えていますが、私の質問に役立つように感じますが、良い説明が見つからないようです。

+3

文字列がEDIT2については 'のstd :: STRING' –

+0

の一部であり、それらはある警備員、そしてあなたの問題とは全く無関係が含まれています。 –

答えて

5

stringおよびvectorは、iostreamとは別のものであり、3つともいずれもstd名前空間の一部です。ヘッダーファイルで適切に修飾するだけです。

Assignment.h

#include <string> 
#include <vector> 
// no need to #include <iostream> 

struct Obj 
{ 
    // fully qualified with std:: 
    std::string s_; 

    // same: 
    std::vector<std::string> v_; 
}; 
0

確かに自分のヘッダーで使用している場合は、stringのヘッダーを含める必要があります。これは、stringメンバを持つオブジェクトのメモリレイアウトをコンパイラが計算する必要があるためです。つまり、stringのレイアウトを計算する必要があります。つまり、完全宣言がstringであることが必要です。

この問題を回避する方法はありませんが、問題が発生した場合はpimpl idiomを使用して対処することができます。あなたは今、もちろん

class std::string; // forward declaration 

class my_class 
{ 
    std::string* psz; 
}; 

:このパターンの利点の1つは、このように(フォワード宣言し、そのクラスの代わりに)最初にその宣言を含める必要がなくても、あなたのクラスのオブジェクトを集約することができますということですstringを作成し、それ自身へのポインタを取得し、そのオブジェクトを手動で管理する責任があります。さらに、その文字列にアクセスするには、追加のポインタ逆参照が必要になります。

2

それはあなたがそれらを必要とし、循環依存関係を作成しない場合は、他のヘッダのヘッダをインクルードしても大丈夫です。 <string>はユーザー生成ヘッダーではないため、ここには該当しません。

あなたのタイプのスコープを指定する代わりに、using namespace std;をヘッダに追加すると、悪い点があります。これを行うと、あなたがあなたのヘッダーを含め、すべてのファイルでnamespace stdの内容であなたのグローバル名前空間に取り込みます。

0

std::stringが実際にbasic_stringテンプレートのtypedefあるのではい、あなたは<string>を含める必要があります。

typedef basic_string<char> string; 

クラスの場合は、定義を含まずに宣言することもできます。

class string;