まず、「バインディング」がコンパイル時にわかっているかどうかを知ることは有益でしょう。もしそうなら、私はあなたにポリシークラスを調べるよう勧めます。
それ以外は、2つのソリューションの組み合わせ、つまりインターフェイスアプローチを使用して、シグナル/フリー機能のリレイヤーとして機能する1つのインターフェイスを実装します。このようにしてデフォルトの動作を持たせることができます。インターフェイス全体を実装するカスタムオブジェクトを追加し、基本的に2つのアプローチの利点と柔軟性を得ることができます。
ここに提案されたアプローチの基本的な例があります。私はそれが助けになることを願っています。
#include <functional>
using namespace std;
template <class ObserverPolicy>
class Animation : public ObserverPolicy{
};
class MonolithicObserver{
public:
void play(){
state = playing;
}
void pause(){
if(playing == state)
state = stopped;
}
void stop(){
state = stopped;
}
private:
enum {playing, paused, stopped} state;
};
struct doNothing{
static void play(){}
static void pause(){}
static void stop(){}
};
struct throwException{
class noPlay{};
class noPause{};
class noStop{};
static void play(){
throw noPlay();
}
static void pause(){
throw noPause();
}
static void stop(){
throw noStop();
}
};
template <class DefaultPolicy = doNothing>
class FreeFunctionObserver{
public:
void play(){
if(playHandle)
playHandle();
else
DefaultPolicy::play();
}
void pause(){
if(pauseHandle)
pauseHandle();
else
DefaultPolicy::pause();
}
void stop(){
if(stopHandle)
stopHandle();
else
DefaultPolicy::stop();
}
void setPlayHandle(std::function<void(void)> p){
playHandle = p;
}
void setPauseHandle(std::function<void(void)> p){
pauseHandle = p;
}
void setStopHandle(std::function<void(void)> p){
stopHandle = p;
}
private:
std::function<void(void)> playHandle;
std::function<void(void)> pauseHandle;
std::function<void(void)> stopHandle;
};
void play(){}
void pause(){}
void stop(){}
int main(){
Animation<FreeFunctionObserver<> > affo;
affo.setPlayHandle(play);
affo.setPauseHandle(pause);
affo.setStopHandle(stop);
affo.play();
affo.pause();
affo.stop();
Animation<FreeFunctionObserver<throwException> > affot;
try{
affot.play();
}
catch(throwException::noPlay&){}
Animation<MonolithicObserver> amo;
amo.play();
amo.pause();
amo.stop();
}
hereを試すことができます。この例では特に、ポリシークラスを使用しているため、インターフェイスは「正式に定義されていません。また、setPlayHandleのようにインターフェイスを「充実」することができます。しかし、実行時バインディングと同様のことができます。
に慣れます1 "となる。 –
'std :: bind'を使用するのが奇妙な構文(特に' OnWhatever'仮想関数とのインタフェースに比べて)であれば、あなたの言語を再考するべきです。 –
@ChristianRau私のためではありませんが、私はコードベースで働く唯一の人ではありません。 – Felics