私は組み込みプロジェクトのためのC++クラスライブラリを構築しています。 私が持っている概念の1つはTaskという名前のクラスです。 タスクには2つのメンバーがあります。 整数IDとコールバック関数ポインタC++引数を引数としないコールバックを呼び出す - より良い解決策
コールバックはユーザーによって作成され、クラスのコンストラクターに渡されます。
私は、ユーザーに次のオプションを与えたい:
- ユーザがタイプ
void (*)(unsigned int)
の機能を使用することができますタイプvoid(*)(void)
- の機能を使用することができます。そのパラメータは、コールバックが呼び出されたときのタスクのIDでなければなりません。
- ユーザは、タスクはまた、コールバック関数を呼び出すexecute()メソッドを持って
異なるタスクのために上記の関数の種類の組み合わせを使用することができます。このメソッドは、必要に応じて、タスクIDを引数として提供する必要があります。
タスクに 'has_arguments'という名前のbooleanメンバーを追加して、それが設定されていた関数ポインタのタイプコードで与えられています。 また、コールバックメンバのために共用体を使うこともできますし、実行時にvoidポインタを使って適切なものにキャストすることもできます。 タスクの実行には、 'has_arguments'メンバーをチェックし、ポインタを適切な型にキャストし、コールバックを正しい方法で呼び出します。
しかし、この余分なメンバーとチェックを避ける方法はありますか?
void(*)(unsigned int)への関数ポインタを常にキャストしようとしましたが、呼び出すときに常に引数を指定しようとしました。そしてそれは働いた。
引数を引数とする関数を呼び出すのは悪いですか? それは私のために働いたが、それは本当に悪い習慣であると思う。 代わりに私が実装できるものは何ですか?
私は、可変引数リストを持つ関数を作るためにユーザに指示したくありません。私はそれが悪いが、引数で引数を取らない関数を呼び出すことで、彼らに簡単なタスクに依存しない関数を使用する自由を残し またはそのタスクID
暖かいC言語の代わりに 'C++'を実際にコーディングしているのであれば、プレーン関数ポインタの代わりに 'std :: function'を使いたいと思っています。 –
@SamVarshavchikこれは組み込みシステムのためのものではありません。 – Justin
タスクが常に「id」を持っている場合、あなたはいつもそれをユーザに返すのですか? 2つの異なるタイプのコールバックをまったく許可するのはなぜですか?パラメータに 'int'値を渡すのは簡単ではなく、ユーザが望むならば無視することができます。しかし、識別のために、常にそれを渡すべきです。もちろん、void型を間違った型にキャストし、コールバックが期待していない余分なパラメータを渡すと、使用する呼び出し規約に応じて問題が発生する可能性があります。 'stdcall'では大したことですが、' cdecl'では大したことではありません。 –