c++でoperator=を定義したclassを継承したものの継承先のclassで有効にならずに戸惑ったので、usingを利用した継承方法を備忘録として記事に残します。
class Base {
public:
int val0 = 0;
int val1 = 0;
Base& operator=(const Base& other) {
val0 = other.val0;
val1 = other.val1;
return *this;
}
bool operator==(const Base& other) const {
return val0 == other.val0 && val1 == other.val1;
}
bool operator!=(const Base& other) const {
return val0 != other.val0 || val1 != other.val1;
}
};
class ExtendedA : public Base {
public:
int multiply() { return val0 * val1; }
};
Base base;
base.val0 = 3;
base.val1 = 4;
ExtendedA extA0;
extA0 = base; // これができない
ExtendedA extA1 = extA0;
std::cout << ((extA0 == base) ? "same" : "different") << "\n";
std::cout << ((extA0 == extA1) ? "same" : "different") << "\n";
引き継ぎたい親のoperatorをusingで宣言すれば使えると分かりました。
class ExtendedA : public Base {
public:
using Base::operator=;
};
Base base;
base.val0 = 3;
base.val1 = 4;
ExtendedA extA0;
extA0 = base; // できた
なお、定義時に親要素を参照したい場合は、それ用のconstructorの定義が必要でした。
class ExtendedA : public Base {
public:
ExtendedA() {}
ExtendedA(const Base& other) {
Base::operator=(other);
}
};
Base base;
base.val0 = 3;
base.val1 = 4;
ExtendedA extA0 = base; // constructorがあると、定義時の代入が可能になる
そして、不思議なことに上記のconstructorを定義すると operator= のusingの宣言が無くても代入可能になりました。
(constructorがoperator=も兼ねるのか、自分が把握していない仕様です。)
class ExtendedA : public Base {
public:
ExtendedA() {}
ExtendedA(const Base& other) {
Base::operator=(other);
}
// using Base::operator=;
};
Base base;
base.val0 = 3;
base.val1 = 4;
ExtendedA extA0;
extA0 = base; // constructorの宣言により、なぜかできる
試した環境
g++ (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0
construstorを定義したらoperator=の宣言が不要になる不思議な挙動を確認したものの、親要素の operator= を引き継ぐには using を使えば良いと分かりました。
調査しながら試行錯誤していたらこの記述を把握したのですが、参照元のサイトのurlを書き留め忘れたかgoogle検索上部のgemini(googleの学習機)が表示した情報だったため、参考リンクは無いです。
0 件のコメント :
コメントを投稿