オブジェクトのスライシングと多相の概念を試しながら、私が期待していたこのコード例を思いつきました。派生したFunctorTrue
クラスの関数呼び出し演算子は、親のFunctor
クラスの代わりに呼び出されます。オブジェクトのスライスはコンストラクタの実装に依存していますか?
注:run this example in Ideoneにすることができます。
class Dispatcher {
public:
const Functor & mFunctor;
Dispatcher(const Functor & functor): mFunctor(functor) {}
Dispatcher(const Functor && functor): mFunctor(functor) {
cout << "Constructor with rvalue" << endl;
}
void dispatch(){
cout << boolalpha << mFunctor() << endl;
}
};
int main() {
Dispatcher dt = Dispatcher(FunctorTrue());
dt.dispatch(); // returns false
}
注:あなたがalso run this example in Ideoneでき
は、私はラインを印刷するDispatcher
クラスのコンストラクタを変更した場合、親の関数呼び出し演算子が代わりに呼び出されますことを見出しました。予期しない動作が原因Dispatcher
クラスのメンバ変数mFunctor
のタイプで、dispatch
方法が唯一の効果的の関数呼び出し演算子を呼び出して、オブジェクトの「基底クラス部分」について知っている、と考えるのは私を導いたこと
基本クラスしかし、それは元の例では当てはまりません。私はすべてを混乱させてしまいます。
私の質問は以下のとおりです。
1)なぜコンストラクタの変化はFunctor > FunctorTrue
クラス階層に呼び出されるメソッドを変更していますか?
2)バリエーションがデフォルトのコンストラクタが行う最適化に関連する場合、その最適化とはどのように指定できますか?
ありがとうございます。
ありがとうございます!私が似たようなものを見つけたのは初めてのことかもしれません。誰かがその問題の根本的な原因を指摘するのは初めてです。未定義の動作は、私が通常バグの原因として考えているものではありません。あなたの応答は私にその変更を促してくれました^^ – levelont
もう一度待ってください... 'FunctorTrue()'の寿命を一時的に延ばさない 'Dispatcher'クラスの' mFunctor'メンバの定数はどうですか? – levelont
@levelont:一時的な有効期間は間接的に延長されません。メインの視点から考えてみましょう。どのようにして(一般的に)コンストラクタが参照を保持しようとしていたのでしょうか? –