仮想代入演算子の実装で遊んでいる間、私はおかしな振る舞いで終わりました。g ++ 4.1、4.3、およびVS 2005は同じ動作を共有するため、これはコンパイラの不具合ではありません。
基本的に、virtual operator =は、実際に実行されているコードに関して、他の仮想関数とは異なる動作をします。
struct Base {
virtual Base& f( Base const & ) {
std::cout << "Base::f(Base const &)" << std::endl;
return *this;
}
virtual Base& operator=( Base const & ) {
std::cout << "Base::operator=(Base const &)" << std::endl;
return *this;
}
};
struct Derived : public Base {
virtual Base& f( Base const & ) {
std::cout << "Derived::f(Base const &)" << std::endl;
return *this;
}
virtual Base& operator=( Base const & ) {
std::cout << "Derived::operator=( Base const & )" << std::endl;
return *this;
}
};
int main() {
Derived a, b;
a.f( b ); // [0] outputs: Derived::f(Base const &) (expected result)
a = b; // [1] outputs: Base::operator=(Base const &)
Base & ba = a;
Base & bb = b;
ba = bb; // [2] outputs: Derived::operator=(Base const &)
Derived & da = a;
Derived & db = b;
da = db; // [3] outputs: Base::operator=(Base const &)
ba = da; // [4] outputs: Derived::operator=(Base const &)
da = ba; // [5] outputs: Derived::operator=(Base const &)
}
その結果、仮想演算子=は、実際の派生オブジェクト([1])を介して呼び出されたときに演算子のベースバージョンを呼び出すことにより、同じシグネチャを持つ他の仮想関数とは異なる動作をします([1]と比較して[0])。 )または派生参照([3])は、ベース参照([2])を介して呼び出された場合、または左辺値または右辺値のいずれかがベース参照であり、他の派生参照([4]、 [5])。
この奇妙な振る舞いに対する賢明な説明はありますか?