[英]How to get rid of a dynamic_cast here?
我正在为我的游戏制作一个简单的图形引擎。
这是界面部分:
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);
}
}
在这里使用dynamic_cast是否有意义? 有办法避免吗?
您可以尝试消除这种担忧吗?
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 DrawContext
{
virtual void set_texture(Texture* texture) = 0;
};
class GLDrawContext : public DrawContext
{
virtual void set_texture(Texture* texture);
};
void GLDrawContext::set_texture(Texture* texture)
{
texture->set_texture();
}
当然,请使用static_cast,尽管如果传入假指针,您将丢失一些错误处理。 我们使用assert_cast的思想来动态调试构建,并使用静态的发布来解决此类问题。
我认为避免dynamic_cast的标准方法是将一个虚拟方法添加到Texture类中:
virtual int get_texture_handle() const {return -1;}
然后仅在您的GLTexture类中重写该方法:
virtual int get_texture_handle() const {return gl_texture->handle;}
然后,您的调用代码将如下所示:
int handle = texture->get_texture_handle();
if (handle >= 0) glBindTexture(GL_TEXTURE_2D, handle);
一种稍微不同的方法,涉及修改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>();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.