今日軽くハマったミスの備忘録。
代入演算子をオーバーロードしたらハングした
それが代入演算子というのは作業の経緯からすぐ分かったが、原理がすぐには分からなかった。
そもそもやりたかったことは
- 親クラスの中身を子クラスにコピーしたい
- 親クラスのフィールドが private だったので個別にコピーできず
- 親クラスの代入演算子でコピーしよう
原理と解決
問題のコード
class Base
{
private:
int m = 1;
};
class Child : public Base
{
public:
Child & operator =( const Base& src )
{
*this = src;
return *this;
}
};
int main()
{
Base a;
Child b;
b = a;
}
こういうコードをgccでコンパイルしたら特にwarningが出るでもなくビルドできたので走らせたら、ハングした。why!?
もちろん本番コードはこれより複雑なやつなので。
仕方なくお試しコードをVC++でやってみたところ、「関数を回帰するとランタイム スタック オーバーフローが発生します。」と言われた。
回帰?あ、再帰呼び出しか!
*this = src;
oh... そういうことか...
親クラス同士は関係ないから解決策は当然以下の通り。
Child & operator =( const Base& src )
{
*(static_cast<Base*>(this)) = src;
return *this;
}
文章を推敲してちゃんと答えが途中に出てた。「親クラスの代入演算子でコピーしよう」って言ってて出来てなかったんじゃん。
普段あまりやらないことすると、とんでもないミスを犯しがちですぅぁぁぁ