私は、opengl コンテキストにレンダリングされたスクラッチビルド コントロールを特徴とするゲーム プロジェクトに取り組んでいます。ボタン、スクロールバー、リストボックスなどです。これらのコントロールの多くはネストされています。たとえば、私のリストボックスにはスクロールバーがあり、スクロールバーには 3 つのボタンがあります。
スクロールバーの値が変更されたら、変更に応答する「何らかの」関数 (通常は親オブジェクト内) を呼び出したいと思います。たとえば、リストボックスにスライダーがある場合、スライダーをインスタンス化してから、新しいスライダーにリストボックスの「onScroll(float)」関数を呼び出すように指示する必要があります。すべてのコントロールは共通の基本クラスを共有しているため、「base* 親」の親ポインターを使用して、「parent->onScroll(val)」を実行できます。ただし問題は、親がベースから継承しない場合にどうなるかです。実行する仮想 onScroll() がないため、トップレベルの親は、子コントロールの値が変更されたかどうかを定期的に確認する必要があります。これは、子さえ持たない可能性があるため、他のコントロールも混乱させます。
より良い解決策は、親によって設定され、必要に応じて子によって呼び出される汎用関数ポインタ (コールバックなど) を子オブジェクトに保持させることです。このようなもの:
typedef (*ptFuncF)(float);
class glBase {
public:
//position,isVisible,virtual mouseDown(x,y),etc
};
class glDerivedChild : public glBase {
public:
glDerivedChild();
~glDerivedChild();
void changeValue(float fIn) {
Value = fIn; //ignore these forward declaration errors
(*callBack)(fIn);
}
void setCallBack(ptFuncF pIn) {callBack = pIn;}
ptFuncF callBack;
float Value;
};
class glDerivedParent : public glBase {
public:
glDerivedParent() {
child = new glDerivedChild();
child->setCallBack(&onScroll);
}
~glDerivedParent() {delete child;}
void onScroll(float fIn) {
//do something
}
glDerivedChild* child;
};
class someFoo {
public:
someFoo() {
child->setCallBack(&setValue);
}
void setValue(float fIn) {
//do something else
}
glDerivedChild child;
};
私は関数ポインタに慣れていないので、(明らかに)多くのことを間違っていることを知っています。「typedef (glBase::*ptFuncF)(float);」のようなものが含まれているのではないかと思います。「onScroll(f)」はオーバーライドされた仮想関数であり、おそらく「virtual void childCallBack(float)」のような一般名が付いています。ソリューションをできるだけバニラに近づけたいので、boost のような外部ライブラリは避けたいと思います。私は 8 時間のほとんどの間、これについて頭を悩ませてきました。誰かが助けてくれることを願っています。ありがとう!