[解決済み] なぜ#include <string>はスタックオーバーフローエラーを防いでいるのですか?
質問
これは私のサンプルコードです。
#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>
. もし私が
右クリック --> Go to Definition"
をクリックすると、両方の行が同じ行を指しています。
xstring
ファイル内の同じ行を指しています。
typedef basic_string<char, char_traits<char>, allocator<char> >
string;
しかし、プログラムを実行すると、例外エラーが発生します。
OperatorString.exe の 0x77846B6E (ntdll.dll): 0xC00000FD: スタック オーバーフロー (Parameter: 0x00000001, 0x01202FC4)
をコメントアウトするときにランタイム エラーが発生する理由を考えてみてください。
#include <string>
? 私はVS 2013 Expressを使用しています。
どのように解決するのですか?
確かに、非常に興味深い動作ですね。
をコメントアウトするとランタイムエラーが発生するのですが、何か心当たりはありますか?
#include <string>
MS VC++ コンパイラでエラーが発生するのは、以下のように
#include <string>
がないと
operator<<
に対して定義された
std::string
.
コンパイラがコンパイルしようとするとき
ausgabe << f.getName();
をコンパイルしようとすると
operator<<
に対して定義された
std::string
. これは定義されていないので、コンパイラは代替手段を探します。そこには
operator<<
に対して定義された
MyClass
で、コンパイラはそれを使おうとするのですが、それを使うためには
std::string
を
MyClass
であり、これはまさに
MyClass
には明示的でないコンストラクタがあるからです! そのため、コンパイラは最終的に
MyClass
のインスタンスを生成し、それを再び出力ストリームに流そうとします。この結果、無限の再帰が発生します。
start:
operator<<(MyClass) ->
MyClass::MyClass(MyClass::getName()) ->
operator<<(MyClass) -> ... goto start;
このエラーを回避するためには
#include <string>
が存在することを確認します。
operator<<
に対して定義された
std::string
. また
MyClass
のコンストラクタを明示的にして、このような予期せぬ変換を避けるようにしましょう。
知恵の輪:暗黙の変換を避けるために、引数を1つだけ取る場合はコンストラクタを明示的にします。
class MyClass
{
string figName;
public:
explicit MyClass(const string& s) // <<-- avoid implicit conversion
{
figName = s;
}
const string& getName() const
{
return figName;
}
};
見た目は
operator<<
に対して
std::string
が定義されている場合のみ
<string>
が含まれる場合のみ定義され、そのためすべてがコンパイルされますが、次のような予期せぬ動作が発生します。
operator<<
が再帰的に呼び出され
MyClass
を呼び出すのではなく
operator<<
に対して
std::string
.
を通してということでしょうか。
#include <iostream>
の文字列は一部しか含まれないということでしょうか?
いいえ、stringは完全に含まれています。そうでなければ使うことができません。
関連
-
[解決済み】getline()が何らかの入力の後に使用されると動作しない 【重複あり
-
[解決済み】非静的メンバ関数への参照を呼び出す必要がある
-
[解決済み】テンプレートの引数1が無効です(Code::Blocks Win Vista) - テンプレートは使いません。
-
[解決済み】C++エラー:の初期化に一致するコンストラクタがありません。
-
[解決済み】デバッグアサーションに失敗しました。C++のベクトル添え字が範囲外
-
[解決済み】エラー:不完全な型へのメンバーアクセス:前方宣言の
-
[解決済み】浮動小数点数の乱数生成
-
[解決済み】 while(cin) と while(cin >> num) の違いは何ですか?)
-
[解決済み] なぜパスワードにはStringではなくchar[]が好まれるのですか?
-
[解決済み] なぜlist.join(string)ではなくstring.join(list)なのでしょうか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】構造体のベクター初期化について
-
[解決済み】コンストラクターでのエラー:識別子を期待されますか?
-
[解決済み】C++でユーザー入力を待つ【重複あり
-
[解決済み] 式はクラス型を持つ必要があります。
-
[解決済み] 解決済み] `pthread_create' への未定義の参照 [重複] [重複
-
[解決済み】浮動小数点数の乱数生成
-
[解決済み】クラスのコンストラクタへの未定義参照、.cppファイルの修正も含む
-
[解決済み】 while(cin) と while(cin >> num) の違いは何ですか?)
-
[解決済み】VC++の致命的なエラーLNK1168:書き込みのためにfilename.exeを開くことができません。
-
[解決済み] 配列のベクトルを扱う正しい方法