0

最初の質問はABと の 3 つのクラスがあるというものでしたCAには へのリンクと呼び出しがありB、 には へのリンクと呼び出しがありますC。しかし、静的メソッドCへの呼び出しがあります。Aそして、この静的呼び出しを機能させることができません。

しかし、コードを切り詰める際の不正確さについてみんなが私を咳払いしたので、クラスの実際の名前は GameRenderer,GameViewFieldView. GameRendererには へのリンクと呼び出しがありGameView、 には へのリンクと呼び出しがありますFieldView。しかし、静的メソッドFieldViewへの呼び出しがあります。そして、この静的呼び出しを機能させることができません。GameRenderercreateGlTextureFromResource

これが完全で実際のヘッダーです GameRenderer.h

// GameRenderer.h
#ifndef GAME_RENDERER
#define GAME_RENDERER

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>

#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>

namespace game{
    class GameModel;
    class GameView;

    class GameRenderer {
            jobject*    context;
            jobject*    gameOverHandler;
            static JNIEnv*     env;
            static jobject*    jparent;

            GameModel*  gameModel;
            GameView*   gameView;

            glm::mat4 mProjMatrix;
            glm::mat4 mVMatrix;

        public:
            GameRenderer(jobject* context, jobject* gameOverHandler, JNIEnv* env, jobject* jparent);

            void onSurfaceCreated();
            void onDrawFrame();
            void onSurfaceChanged(int width, int height);
            void setMotionDirection();

            static int* getImagePixels (int imageId, int width, int height);
            static void createGlTextureFromResource (int resourceId, int textureId);
    };
}

#endif 

GameView.h

// GameView.h
#ifndef GAME_VIEW
#define GAME_VIEW

#include <glm/glm.hpp>

namespace game{
    class GameModel;
    class FieldView;

    class GameView {
        GameModel* gameModel;

        FieldView* fieldView;
        public:
        GameView(GameModel* gameModel);
        void draw(glm::mat4 mProjMatrix, glm::mat4 mVMatrix);
    };
}

#endif 

FieldView.h

// FieldView.h
#ifndef FIELD_VIEW
#define FIELD_VIEW

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>

#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>

#include "GLESUtils.h"

namespace game{
    class GameRenderer;

    class FieldView {
        static const int FLOAT_SIZE_BYTES = 4;
        static const int TRIANGLE_VERTICES_DATA_STRIDE_BYTES = 5 * FLOAT_SIZE_BYTES;
        static const int TRIANGLE_VERTICES_DATA_POS_OFFSET = 0;
        static const int TRIANGLE_VERTICES_DATA_UV_OFFSET = 3;

        glm::mat4 mMMatrix;
        glm::mat4 mMVPMatrix;

        int mProgram;
        int mTextureID;
        int muMVPMatrixHandle;
        int maPositionHandle;
        int maTextureHandle;

        public:
        FieldView();
        void draw(glm::mat4 mProjMatrix, glm::mat4 mVMatrix);
    };
}

#endif 

ここに FieldView.cpp のカット バージョンがあります

// FieldView.cpp
#include <jni.h>  
#include <string.h>  
#include <android/log.h>  

#include "FieldView.h"
#include "GameRenderer.h"

#define  LOG_TAG    "NDK_FieldView"
#define  LOGI(...)  __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)

namespace game{
    static GLfloat mTriangleVerticesData[] = {...};

    static const char mVertexShader[] = "...\n";

    static const char mFragmentShader[] = "...\n";

    FieldView::FieldView() {
        mProgram            = -1;
        mTextureID          = -1;
        muMVPMatrixHandle   = -1;
        maPositionHandle    = -1;
        maTextureHandle     = -1;

        mProgram = GLESUtils::createProgram(mVertexShader, mFragmentShader);
        GLESUtils::checkGlError("createProgram mProgram");
        if (mProgram == 0) {
            LOGI("program not created exiting");
            return;
        }
        maPositionHandle = glGetAttribLocation(mProgram, "aPosition");
        GLESUtils::checkGlError("glGetAttribLocation aPosition");
        if (maPositionHandle == -1) {
            return;
        }
        maTextureHandle = glGetAttribLocation(mProgram, "aTextureCoord");
        GLESUtils::checkGlError("glGetAttribLocation aTextureCoord");
        if (maTextureHandle == -1) {
            return;
        }

        muMVPMatrixHandle = glGetUniformLocation(mProgram, "uMVPMatrix");
        GLESUtils::checkGlError("glGetUniformLocation uMVPMatrix");
        if (muMVPMatrixHandle == -1) {
            return;
        }

        /*
         * Create our texture. This has to be done each time the
         * surface is created.
         */

        GLuint textures[] = {0};
        glGenTextures(1, &textures[0]);

        mTextureID = textures[0];
        glBindTexture(GL_TEXTURE_2D, mTextureID);

        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

        // here is the actual problem, I get the following error on this line
        // FieldView.cpp: In constructor 'game::FieldView::FieldView()':
        // FieldView.cpp:89:9: error: incomplete type 'game::GameRenderer' used in nested name specifier

        GameRenderer::createGlTextureFromResource(0x7f040004, mTextureID);
    }

    void FieldView::draw(glm::mat4 mProjMatrix, glm::mat4 mVMatrix) {
        //... doesn't matter
    }
}

私が正しく理解していれば、前方宣言を使用する必要があり、サークルを壊すために少なくとも1つの場所でヘッダーのインクルードを使用しないでください。メソッドの呼び出し。コンパイラ エラーは にあります。呼び出しFieldView.cppの近くのコード内のコメントを参照してください。GameRenderer::createGlTextureFromResource(0x7f040004, mTextureID);

これらすべての編集後、質問は実際には同じままです。ここで何が間違っていますか? どこかで非常に悪い設計手法を使用していると思います。

私の初歩的な不正確さを許してください。

4

4 に答える 4

5

私はこれがうまくいくと思います:

  • 他のヘッダーからのヘッダーのインクルードを停止します。それらは必要ありません。これは、最後の行としてのみ含まれているという事実から明らかです。原則として、ヘッダーに含めるものはできるだけ少なくし、可能な限り単純な宣言 ( などclass B;) を避けるようにしてください。

  • A.hC.hfromの両方を含めますC.cpp。どちらのクラスも から直接使用されるC.cppため、両方のヘッダーを含める必要があるのは理にかなっています。

于 2012-09-30T10:51:54.467 に答える
4

少なくとも投稿したコードにはB.h、下部などに含める理由はありませんA.h。これらのインクルードを実装ファイルに入れる必要があります。

// A.cpp
#include "A.h"
#include "B.h"
namespace game
{
 ....
}
于 2012-09-30T10:50:42.147 に答える
1

私が知る限り、#include "Ah" は Ch ヘッダー ファイルで何も購入していません。C.cpp ヘッダーには Ah と Ch が含まれている必要があります。同様に、Bh の末尾にも Ch が含まれており、前と同じように何も購入できません。

A.h - include no other headers, forward decl class C;
B.h - include no other headers, forward decl class C;
C.h - include no other headers, forward decl class A

A.cpp - include A.h, C.h
B.cpp - include A.h, B.h, C.h
C.cpp - include A.h, C.h

.cpp ファイルのカスタム ヘッダーを 1 つだけ含めるというマントラがあるようです。これは、マルチクラス/マルチヘッダー階層にはほとんど当てはまりません。

于 2012-09-30T10:52:08.700 に答える
0

あなたのコードは私のためにコンパイルされます。Cのコンストラクターをデフォルトのコンストラクターに変更することによりますが(したがって、C.cppのコードには宣言があります)。

于 2012-09-30T10:53:40.543 に答える