これは私のサンプルコードです。
#include <iostream>
#include <string>
using namespace std;
class MyClass
{
string figName;
public:
MyClass(const string& s)
{
figName = s;
}
const string& getName() const
{
return figName;
}
};
ostream& operator<<(ostream& ausgabe, const MyClass& f)
{
ausgabe << f.getName();
return ausgabe;
}
int main()
{
MyClass f1("Hello");
cout << f1;
return 0;
}
#include <string>
をコメントアウトすると、コンパイラエラーは発生しません。これは、#include <iostream>
を介して含まれているためです。 I "右クリック->定義に移動" Microsoft VSでは、両方ともxstring
ファイルの同じ行を指します。
typedef basic_string<char, char_traits<char>, allocator<char> >
string;
しかし、プログラムを実行すると、例外エラーが発生します。
OperatorString.exeの0x77846B6E(ntdll.dll):0xC00000FD:スタックオーバーフロー(パラメーター:0x00000001、0x01202FC4)
#include <string>
をコメントアウトするときにランタイムエラーが発生する理由は何ですか? VS 2013 Expressを使用しています。
問題は、コードが無限再帰を実行していることです。 std::string
(std::ostream& operator<<(std::ostream&, const std::string&)
)のストリーミング演算子は<string>
ヘッダーファイルで宣言されていますが、std::string
自体は他のヘッダーファイル(<iostream>
と<string>
)。
<string>
を含めない場合、コンパイラはausgabe << f.getName();
をコンパイルする方法を見つけようとします。
MyClass
のストリーミング演算子とstd::string
を許可するコンストラクターの両方を定義したため、コンパイラーは( 暗黙の構築 を使用して)再帰呼び出しを作成します。 。
explicit
コンストラクター(explicit MyClass(const std::string& s)
)を宣言すると、ストリーミングオペレーターをstd::string
で呼び出す方法がないため、コードはコンパイルされなくなり、 <string>
ヘッダーを含めます。
編集
私のテスト環境はVS 2010であり、警告レベル1(/W1
)から開始して、問題について警告します。
警告C4717: 'operator <<':すべての制御パスで再帰的、関数によりランタイムスタックオーバーフローが発生します