5

インスタンス関数 (またはメソッド?) を持つクラスがあります。インスタンス内から、これらの関数へのポインターをライブラリーに渡そうとします。ライブラリは静的関数を想定しています。

ポインタをコールバック関数に渡すと、コンパイラは関数が静的でないと文句を言います。静的にしようとしましたが、そうすると、関数内からインスタンス フィールドにアクセスできなくなります。

どうすればこれを回避できますか?

同様の質問は、メソッドを静的にすることを提案するCコールバック関数としてC++クラスメンバー関数を使用することです。しかし、私にはそれができないか、どうすればできるかわかりません。

コード

GlutController::GlutController (int argc, char **argv) {

   // stuff ..

   // Register callbacks
   glutSpecialFunc( OnSpecialKeys );  // Error, need static functions
   glutReshapeFunc( OnChangeSize );   // Error...
   glutDisplayFunc( OnRenderScene );  // Error...

   // stuff ..
}

GlutController::~GlutController() {

}

void GlutController::OnChangeSize(int aNewWidth, int aNewHeight){

   glViewport(0,0,aNewWidth, aNewHeight);
   mViewFrustrum.SetPerspective( APP_CAMERA_FOV,             // If this function is 
            float( aNewWidth ) / float( aNewHeight ),        // static, this won't 
            APP_CAMERA_NEAR,                                 // work
            APP_CAMERA_FAR );
   mProjectionMatrixStack.LoadMatrix(                        // Same here
            mViewFrustrum.GetProjectionMatrix() );
   mTransformPipeline.SetMatrixStacks(mModelViewMatrixStack, // Same here  
            mProjectionMatrixStack);

}

void GlutController::OnRenderScene(void){
   mGeometryContainer.draw();                                // Won't work if static
}

void GlutController::OnSpecialKeys(int key, int x, int y){
   mGeometryContainer.updateKeys(key);                       // Won't work if static
}

免責事項 : C++ を始めたばかりです。私は Accelerated C++ をすべて読みましたが、これはこの言語を試す最初のプロジェクトです。私のバックグラウンドは Java です。

4

4 に答える 4

7

あなたがやろうとしていることは不可能です。これはglut実際には のせいです。

問題はこれです:

  • glutデータを渡さずに関数を呼び出したい
  • 関数でいくつかのデータを使用したい場合、

これは相反するニーズです。glutグローバル変数を安全に使用できると判断したと思います。

したがって、1 つの解決策は、 static 関数を static data とともに使用することです。または、より良い解決策はSDLに切り替えることです。

于 2012-08-03T09:14:21.057 に答える
3

要するに、できません。C++ メンバー関数は、実際にはオブジェクトのインスタンスに「リンク」されています。下位レベルには、1 つの追加パラメーターがあります。これは、実際にはこのオブジェクトのインスタンスへのポインターです。

したがって、静的関数を使用する必要があります。また、glut では現在のインスタンスを識別するパラメーターを渡すことができないため、回避策を考え出す必要があります。最も簡単な回避策は、静的メンバーを使用することです。あなたの GlutController がシングルトンなら (私はそうだと思います)、問題ありません。

于 2012-08-03T09:18:40.950 に答える
2

GlutInstanceを指すファイルスコープの静的変数(別の回答で言及されている静的関数+静的データ)を使用することは可能であり、明らかに安全です。

static GlutController* s_this;

static void s_OnChangeSize(int w, int h) { s_this->OnChangeSize(w, h); }

GlutController::GlutController (int argc, char **argv) { 
   s_this = this;

   glutSpecialFunc(s_OnSpecialKeys);
}

GlutController::~GlutController() { s_this= 0; } 

void GlutController::OnChangeSize(int w, int h) { /* non-static stuff */ }

s_thisローカルファイルにのみ表示されます。たとえば、別のファイルからGlutControllerコンストラクターを呼び出すコードには表示されません。

于 2012-08-03T11:03:01.617 に答える
1

from関数のメンバー関数を呼び出すには、static methodと(おそらく静的)が必要です。instanceinstancestatic

このようなもの:

//static method
void MyClass::myCallback()
{
    static MyClass instance; //or you can store your in instance in some Singleton, or
    //possibly create a temporary
    instance.nonStaticMethod();
}
于 2012-08-03T09:14:39.120 に答える