クラスのすべての関数呼び出しの直前にいくつかのコード(おそらく関数)を実行し、そのクラスを継承するクラスのすべての関数を実行したいと考えています。私は実際にすべての機能を編集することなくこれをやりたいのですが、そのようなことも可能ですか?C++でクラスを呼び出すたびにコードを実行する
直前に呼び出されているのではなく、すべての関数呼び出しの最初の命令として呼び出された関数を持つことで解決します。
クラスのすべての関数呼び出しの直前にいくつかのコード(おそらく関数)を実行し、そのクラスを継承するクラスのすべての関数を実行したいと考えています。私は実際にすべての機能を編集することなくこれをやりたいのですが、そのようなことも可能ですか?C++でクラスを呼び出すたびにコードを実行する
直前に呼び出されているのではなく、すべての関数呼び出しの最初の命令として呼び出された関数を持つことで解決します。
AspectC++です。私は自分で使ったことはありませんが、Aspect-Oriented Programmingパラダイムはこの問題を解決しようとします。
基本型のオブジェクトを受け取り、周囲の関数を呼び出して呼び出したい関数を呼び出すラッパークラスを作成するには多少不便な方法です。これはdecoratorのようなものになります。
これは、プロファイラのように聞こえます。プロファイリングツールのソースを見ましたか?
もっと契約的なプログラミングに似ています。契約が壊れていないことを確認する前と後の条件を確認する。 –
非仮想インターフェイスイディオムを使用することをお勧めします。すべてのパブリック関数は非仮想です。すべての仮想機能は保護されているか、またはプライベートです。パブリックメンバーは仮想メンバーに呼び出しを委任し、通常はインライン関数として実装されます。
IOStreamがSTLで実装される方法です。 C++ Wikibooksで詳細を読むことができます。
目的:1つの場所でクラス階層全体のコードフラグメント(例えば、不変チェック、ロックの取得/解放)の前と後の共通のモジュール化/リファクタリング。
よろしく、
Ovanes
は、あなたができる最善のは、保護されたとして、仮想関数のセットを宣言し、クラスから継承し、開発者が仮想関数をオーバーライドすることです。基本クラスが使用するインタフェースはpublicにすることができます。これは、保護された仮想メソッドに情報を渡す前に、目的のコードを実行します。例えば
:
class Base {
public:
void MyMethod(void) { /* Insert code here */ YourMethod(); }
protected:
virtual void YourMethod(void) {}
};
開発者は、彼が特定のサブクラスを持っていることを知っている場合、彼はまだのdynamic_castを使用して、そして彼自身のメソッドのセットを使用するだけで、あなたのコードをバイパスすることができます。このように、基本C++言語に関係しない、すでに投稿されている他の提案に従うことをお勧めします。
私は、テストされているクラスに侵入することを伴わない他の方法について考えることができます。 –
もう1つのことは、[boost/C++ 0X] shared_ptrラッパーのように、クラスインスタンスポインタを返す前にカスタム関数を ' - >'オーバーロードで呼び出すことです。これには、基本クラスではなく、使用法の変更が含まれています。同じ効果を得るには、これを数回使用しました。ただ別の考え。
これは優れた選択肢のように聞こえます。 – Greg
以下は過度の過ちかもしれませんが、どうですか?
またCuriously recurring template pattern (CRTP)でこれを行うことができます。
g++
を使用すると、コンパイル単位ごとにオプション-pg
を使用すると、コンパイラはすべての機能の開始時に関数mcount
の呼び出しを生成します。 mcount
は通常gprof
のようなプロファイリングツールで提供されますが、あなた自身で実装することもできます。 Cの関数としてそれを実装し、gcc
のような純粋なCコンパイラでコンパイルすることにより、すなわち - ただし
mcount
はCリンケージを(スタイル名-マングルされたとC++ではない)があることを確認する必要があります。mcount
を含むコンパイル単位は、-pg
でコンパイルされません。
私はアスペクトに厳密に反対しています。アスペクトは、あなたのコードにどのくらいのコストがかかり、どのコードに拡張されるか分からないからです。 C++でこれらをデバッグする方法も明確ではありません。なぜなら、コードを効果的に生成し、関数のエントリポイントを完全に変更する可能性があるからです。 – ovanes