2012-01-04 9 views
2

virtual void Foo()が定義されている抽象的なインターフェイスIが他の関数とともに定義されています。 Fooが再定義されたサブクラスと、Fooが再定義されていないサブクラスがあります。さて、I* piを与えて、Fooが再定義されているかどうかを知ることはできますか?つまり、pi->Foo()I::Foo()またはX::Foo()を呼び出すかどうかを知りたいと思います。Xは、Fooが再定義されたタイプです。これは、&I::Foo&pi->Fooの間の関数ポインタを比較することで行うことができますが、正確な方法はわかりません。実行時に具体的なタイプのpiがわからないので、関数ポインタを直接&I::Foo != &X::Fooと比較することはできません。実行時にC++のチェック関数がオーバーロードされているかどうか

ADD: だから、多くの人が抽象概念と仮想関数の概念に反してデザインが悪いと指摘していました。私がこれをやっている主な理由は、速度を向上させるために空の関数呼び出しをバイパスすることです。 Foo()のいくつかは空ですのでが空の場合はpiのベクトルから削除したいと思います。

+1

なぜですか?関数を呼び出すと、 'I :: foo'で終わるかどうかがわかります。それからあなたは知っているよ! –

+8

好奇心で、なぜこれをやりたいのですか?私は悪いデザインのにおいがする。 –

+0

私が知る限り、動的ディスパッチの結果を保存することはできません。私は[これについて質問があった](http://stackoverflow.com/questions/7451442/hoisting-the-dynamic-type-out-of-a-loop-aka-doing-java-the-c-way)atいくつかのポイント。 Objective-C++ではこれを行うことができます。 –

答えて

1

GCCのエラーメッセージがあなたを教えてくれるようあなたは、以来、&pi->Fooから見つけることができない、

ISO C++には、メンバ関数へのポインタを形成するためにバインドされたメンバ関数のアドレスを取ることを禁じます。

実行時にオブジェクトの種類を知りたい場合は、typeidを使用してください。それ以外の場合は、デザインを再考してください。

+0

'typeid'を使用しても、関数がオーバーライドされているかどうかを知ることはできません。 –

+0

@SethCarnegie:noですが、関数をオーバーライドした型を列挙できます。 –

0

dynamic_castそれぞれFooをオーバーライドする子タイプのそれぞれへのポインタがあり、そのタイプの1つであれば子を呼び出すことができます。使用する構文->を使用してメンバー関数のアドレスを取得することはできません。

しかし、私は本当にこのようなことをする前にあなたのデザインを考え直すと言いました。インターフェースと仮想メソッドのポイントは、あなたが扱っているタイプを知る必要性を避けることです!

関連する問題