C++ 如何摆脱这里的动态角色?
我正在为我的游戏制作一个简单的图形引擎 这是接口部分:C++ 如何摆脱这里的动态角色?,c++,rtti,dynamic-cast,C++,Rtti,Dynamic Cast,我正在为我的游戏制作一个简单的图形引擎 这是接口部分: class Texture { ... }; class DrawContext { virtual void set_texture(Texture* texture) = 0; } 这是实施部分: class GLTexture : public Texture { public: ... GLuint handle; }; void GLDrawContext::set_texture(Textur
class Texture { ... };
class DrawContext
{
virtual void set_texture(Texture* texture) = 0;
}
这是实施部分:
class GLTexture : public Texture
{
public:
...
GLuint handle;
};
void GLDrawContext::set_texture(Texture* texture)
{
// Check if it's GLTexture, otherwise do nothing.
if (GLTexture* gl_texture = dynamic_cast<GLTexture*>(texture))
{
glBindTexture(GL_TEXTURE_2D, gl_texture->handle);
}
}
class-GLTexture:公共纹理
{
公众:
...
胶柄;
};
void GLDrawContext::设置纹理(纹理*纹理)
{
//检查它是否为GLTexture,否则什么也不做。
if(GLTexture*gl_texture=dynamic_cast(纹理))
{
glBindTexture(GL_纹理\u 2D,GL_纹理->句柄);
}
}
在这里使用dynamic_cast有意义吗?有什么方法可以避免吗?当然可以,使用static\u cast,但是如果传入一个伪指针,则会丢失一些错误处理。我们使用assert\u cast思想来动态调试构建,使用static for release来绕过RTTI来解决这类问题。当然,可以使用static\u cast,但是如果传入一个伪指针,将丢失一些错误处理。我们使用assert_cast思想来动态调试构建和静态发布,以绕过RTTI进行此类操作。我认为避免动态_cast的标准方法是向Texture类添加虚拟方法:
virtual int get_texture_handle() const {return -1;}
virtual int get_texture_handle() const {return gl_texture->handle;}
然后仅在GLTexture类中重写该方法:
virtual int get_texture_handle() const {return -1;}
virtual int get_texture_handle() const {return gl_texture->handle;}
那么您的呼叫代码如下所示:
int handle = texture->get_texture_handle();
if (handle >= 0) glBindTexture(GL_TEXTURE_2D, handle);
我认为避免动态_cast的标准方法是向纹理类添加虚拟方法:
virtual int get_texture_handle() const {return -1;}
virtual int get_texture_handle() const {return gl_texture->handle;}
然后仅在GLTexture类中重写该方法:
virtual int get_texture_handle() const {return -1;}
virtual int get_texture_handle() const {return gl_texture->handle;}
那么您的呼叫代码如下所示:
int handle = texture->get_texture_handle();
if (handle >= 0) glBindTexture(GL_TEXTURE_2D, handle);
你能试着扭转这种担忧吗
class Texture
{
public:
virtual void set_texture() = 0;
};
class GLTexture : public Texture
{
public:
virtual void set_texture();
GLuint handle;
};
void GLTexture::set_texture()
{
glBindTexture(GL_TEXTURE_2D, handle);
}
你能试着扭转这种担忧吗
class Texture
{
public:
virtual void set_texture() = 0;
};
class GLTexture : public Texture
{
public:
virtual void set_texture();
GLuint handle;
};
void GLTexture::set_texture()
{
glBindTexture(GL_TEXTURE_2D, handle);
}
一种稍微不同的方法,涉及修改纹理类
class Texture
{
virtual void bind_texture(){}
};
class GLTexture : public Texture
{
virtual void bind_texture();
};
void GLTexture::bind_texture()
{
glBindTexture(GL_TEXTURE_2D, handle);
}
class DrawContext
{
virtual void set_texture(Texture* texture) = 0;
};
class GLDrawContext : public DrawContext
{
virtual void set_texture(Texture* texture);
};
void GLDrawContext::set_texture(Texture* texture)
{
if( texture )
texture->bind_texture();
}
一种稍微不同的方法,涉及修改纹理类
class Texture
{
virtual void bind_texture(){}
};
class GLTexture : public Texture
{
virtual void bind_texture();
};
void GLTexture::bind_texture()
{
glBindTexture(GL_TEXTURE_2D, handle);
}
class DrawContext
{
virtual void set_texture(Texture* texture) = 0;
};
class GLDrawContext : public DrawContext
{
virtual void set_texture(Texture* texture);
};
void GLDrawContext::set_texture(Texture* texture)
{
if( texture )
texture->bind_texture();
}
作为替代方案,您可以尝试使用泛型来摆脱动态强制转换。泛型将允许您在编译时捕获错误(您永远无法将DirectX纹理传递给GL DrawContext)。此外,动态调度不会产生任何成本,编译器应该能够进行内联
namespace GL_impl {
struct Texture {
GLuint handle;
};
struct DrawContext {
void set_texture(Texture* texture)
{
glBindTexture(GL_TEXTURE_2D, texture->handle);
}
};
} // GL_impl
struct use_GL {
typedef GL_impl::Texture Texture;
typedef GL_impl::DrawContext DrawContext;
};
template <class use_impl>
void f()
{
typedef typename use_impl::Texture Texture;
typedef typename use_impl::DrawContext DrawContext;
Texture t;
DrawContext ctx;
ctx.set_texture(&t);
}
void call_f_with_gl()
{
f<use_GL>();
}
名称空间GL\u impl{
结构纹理{
胶柄;
};
结构DrawContext{
空集_纹理(纹理*纹理)
{
glBindTexture(GL_TEXTURE_2D,纹理->句柄);
}
};
}//GL_impl
结构使用{
typedef GL_impl::纹理;
typedef GL_impl::DrawContext DrawContext;
};
样板
void f()
{
typedef typename使用_impl::纹理;
typedef typename use_impl::DrawContext DrawContext;
纹理t;
DrawContext-ctx;
ctx.set_纹理(&t);
}
无效调用\u f\u和\u gl()
{
f();
}
作为替代,您可以尝试使用泛型来摆脱动态强制转换。泛型将允许您在编译时捕获错误(您永远无法将DirectX纹理传递给GL DrawContext)。此外,动态调度不会产生任何成本,编译器应该能够进行内联
namespace GL_impl {
struct Texture {
GLuint handle;
};
struct DrawContext {
void set_texture(Texture* texture)
{
glBindTexture(GL_TEXTURE_2D, texture->handle);
}
};
} // GL_impl
struct use_GL {
typedef GL_impl::Texture Texture;
typedef GL_impl::DrawContext DrawContext;
};
template <class use_impl>
void f()
{
typedef typename use_impl::Texture Texture;
typedef typename use_impl::DrawContext DrawContext;
Texture t;
DrawContext ctx;
ctx.set_texture(&t);
}
void call_f_with_gl()
{
f<use_GL>();
}
名称空间GL\u impl{
结构纹理{
胶柄;
};
结构DrawContext{
空集_纹理(纹理*纹理)
{
glBindTexture(GL_TEXTURE_2D,纹理->句柄);
}
};
}//GL_impl
结构使用{
typedef GL_impl::纹理;
typedef GL_impl::DrawContext DrawContext;
};
样板
void f()
{
typedef typename使用_impl::纹理;
typedef typename use_impl::DrawContext DrawContext;
纹理t;
DrawContext-ctx;
ctx.set_纹理(&t);
}
无效调用\u f\u和\u gl()
{
f();
}
为什么要使纹理具有多态性?你也打算使用DirectX和软件blitting吗?为什么你需要纹理是多态的?你也打算使用DirectX和软件blitting吗?看起来不错,但我觉得set_texture()实际上不属于纹理类。此解决方案利用OpenGL是一个有状态API。如果我没有使用OpenGL,但是,例如,一个名为EggDraw的假设API,其中绘制三角形的过程是:EGG_DrawTriangle(float*顶点,EGG_TextureHandle*纹理)?所以,如果我使用那个API,我也应该把draw_triangle()方法放到纹理类中?看起来不错,但我觉得set_Texture()实际上不属于纹理类。此解决方案利用OpenGL是一个有状态API。如果我没有使用OpenGL,但是,例如,一个名为EggDraw的假设API,其中绘制三角形的过程是:EGG_DrawTriangle(float*顶点,EGG_TextureHandle*纹理)?所以,如果我使用那个API,我应该把draw_triangle()方法也放到纹理类中?