我是 C++ 的新手,正在从 Java 移植代码。我有一个渲染器类,它有一个将接口(interface)作为参数的方法。这样,调用者可以定义如何呈现其缓冲区。现在,当我尝试“新建”移植类时遇到了麻烦。我收到错误“分配抽象类类型的对象”。这是我认为我需要做一些事情的代码部分:
// 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;
};
...
};
最佳答案
你不应该,也不能像你所做的那样,直接在类中包含接口(interface):
IDrawGLBuffer callback;
这只为接口(interface)分配空间(它不占用任何空间,是抽象的),你无法知道任何实现的大小(它可以而且可能确实继承接口(interface)并添加私有(private)成员)。
你应该做的是传递一个指向接口(interface)实现的指针,然后存储它:
Ctor(IDrawGLBuffer * pDrawImpl);
std::shared_ptr<IDrawGLBuffer> m_DrawImpl;
然后您可以使用指针语法 (a->b(c)
) 从接口(interface)调用方法。
由于编译器不可能知道稍后接口(interface)的实现会有多大,因此使用指针来引用内存(这在某种程度上是已知的)变得非常重要。
我在这里使用了一个 shared_ptr
来帮助自动释放 impl,尽管你可能需要一个 CComPtr
或者如果你的类有点奇怪,boost::侵入式指针
。使用界面时,智能指针是您的好 friend (比平时更频繁)。
关于c++ - 当该类具有嵌套抽象类时,如何分配该类(使用 new)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8029447/