2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

代入演算子のオーバーロードで無限再帰の罠(派生クラス)

Posted at

今日軽くハマったミスの備忘録。

代入演算子をオーバーロードしたらハングした

それが代入演算子というのは作業の経緯からすぐ分かったが、原理がすぐには分からなかった。

そもそもやりたかったことは

  • 親クラスの中身を子クラスにコピーしたい
  • 親クラスのフィールドが 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;
	}

文章を推敲してちゃんと答えが途中に出てた。「親クラスの代入演算子でコピーしよう」って言ってて出来てなかったんじゃん。
普段あまりやらないことすると、とんでもないミスを犯しがちですぅぁぁぁ

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?