2011-11-06 50 views
0

我是C++新手,正在從Java代碼移植。我有一個渲染器類,它具有一個將接口作爲參數的方法。這樣調用者可以定義如何渲染其緩衝區。現在,當我嘗試「移植」上課時,我遇到了麻煩。我收到錯誤'分配一個抽象類類型的對象'。這是我的代碼,我想我需要做一些事情的一部分:當該類有嵌套的抽象類時,我該如何分配一個類(使用new)?

// Interface to the OpenGL ES renderer; consumed by GLView 
struct IRenderingEngine { 
virtual void initialize(int width, int height) = 0; 
virtual void render() const = 0; 
virtual ~IRenderingEngine() {} 
}; 

class Renderer : public IRenderingEngine 
{ 
public: 
    ... 

class IDrawGLBuffer 
{ 
public: 
    virtual ~IDrawGLBuffer() {}; 
    virtual void function(VBODescription vboDescription, 
          ShaderDescription shaderDescription); 
}; 

class ShaderDescription 
{ 
public: 
    ShaderDescription(){}; 
    ShaderDescription(string vertexShaderText, 
         string fragmentShaderText, 
         map<string,GLint>& variableMap, 
         IDrawGLBuffer& callback, 
         int vertexDimensions); 
    GLuint getProgramID() const {return shaderProgramID;}; 
    int getVertexDimensions() const {return vertexDimensions;}; 
    friend class Renderer; 
private: 
    string vertexShaderText; 
    string fragmentShaderText; 
    GLuint shaderProgramID; 
    IDrawGLBuffer callback; 
    int vertexDimensions; 
    map<string,GLint> variableMap; 
}; 

class VBODescription 
{ 
public: 
    VBODescription(){}; 
    VBODescription(string shaderName, 
        map<string, Buffer>& variableMap, 
        GLenum usage, 
        int indexTotal, 
        GLuint textureID); 
    int getIndexTotal() const {return indexTotal;}; 
    GLuint getTextureID() const {return textureID;}; 
    friend class Renderer; 
private: 
    GLenum usage; 
    map<string, Buffer> variableMap; 
    string shaderName; 
    int indexTotal; 
    GLuint textureID; 

}; 

    ... 

}; 
+0

有IRenderingEngine類純虛函數嗎? – Andrey

+3

請發佈完整的代碼。另外請注意,C++嵌套類與Java嵌套類非常不同。沒有存儲在內部類中的外部類的「this」指針。 –

+0

@Joe如果它可能是一個純粹的抽象類。我見過很多。 –

回答

2

你不應該,也不可能輕易,包括直接在類的界面你所做的:

IDrawGLBuffer callback; 

此分配僅用於界面空間(不採取任何房間,是抽象的),你可以不知道任何實現的規模(這可能也可能不會繼承界面並添加私人成員)。

你應該做的是一個指針傳遞到接口的實現,然後存儲:

Ctor(IDrawGLBuffer * pDrawImpl); 
std::shared_ptr<IDrawGLBuffer> m_DrawImpl; 

你再調用使用指針語法(a->b(c))從接口的方法。

由於編譯器不可能知道接口的實現有多大,所以使用指針來引用內存(這在某種程度上是已知的)變得非常重要。

我在這裏使用shared_ptr來幫助自動發佈impl,儘管您可能需要CComPtr或者如果您的課程有點奇怪,boost::intrusive_ptr。在使用接口時,智能指針是你的朋友(不止是定期)。

+0

首選使用'std :: unique_ptr'到'std :: shared_ptr',你不會意外地在類的幾個實例之間共享*「m_DrawImpl」指針。 –

+0

我希望能夠使用虛擬方法來避免使用指針。啊,好吧。我會試試這個,這很有道理。 – Xavier

+0

虛擬方法和指針可以一起使用,一種可以使用另一種。虛擬方法很短,使指針的類型無關緊要;正是如此,你可以做像接口這樣的事情。 – ssube

0

內部類「級IDrawGLBuffer」是無關緊要的,因爲當你創建的新實例的一個實例不會被分配類渲染器(除非渲染器按值包含IDrawGLBuffer的實例,並且您從摘要中省略了該實例)。

如果您創建Renderer的新實例,但Renderer不包含其基類(IRenderingEngine)中的所有純虛函數的覆蓋,將給出錯誤'allocating an object of abstract class type'。通常你的編譯器會告訴你哪些丟失。

編輯:從更新的代碼,它看起來像渲染需要包含的void render() and void initialise(int,int)的定義,但它不會

相關問題