我有一些包装器类,它们将包装C库。在这种情况下为SDL。我会将所有内容简化为必要的细节,如果缺少某些内容,请在评论中告诉我。
例如,我有一个名为texture_t
的类,它将包装SDL_Texture
class texture_t
{
public:
...
private:
SDL_Texture *tex;
}
有时,它可能在shared_ptr
中:
typedef std::shared_ptr<texture_t> texture_ptr_t;
现在,如果我想调用一个以SDL
作为参数的SDL_Texture *
函数,我希望将texture_t
和texture_ptr_t
隐式转换为它。
我在课堂上尝试实现这些运算符:
operator SDL_Texture *(void);
operator const SDL_Texture *(void) const;
但是我仍然遇到no viable conversion from texture_ptr_t to SDL_Texture *
错误。有人可以为我指出正确的方向吗?
答案 0 :(得分:2)
即使在没有shared_ptr
的情况下,如果使用原始指针,也会出现这些错误,所以我会暂时放弃它。
隐式转换仅适用于texture_t
对象,不适用于指向一个指针(智能或其他)的指针。这是行不通的,因为shared_ptr
和哑指针都无法将此转换为无关的指针类型。
因此,要调用任何SDL_func
并进行转换,您需要为texture_t
提供glvalue(引用)。取消引用很容易实现。
SDL_func(*ptr, /* other args */); // ptr can be a dumb pointer too.
但是说了这么多,感觉就像是一个抽象的泄漏。如果您努力包装SDL_Texture*
,请不要半途而废。让texture_t
是全值语义类型,它通过SDL库提供抽象的操作。不要在知道自己使用哪个库的情况下调用代码。以后需要时,它将使切换库更加容易。
答案 1 :(得分:0)
C ++隐式转换为编码器提供了强大的功能。使用一个转换运算符,就可以扩大一个类的接口。这是您想做的,我认为这是个好主意。
但是您应该知道,隐式转换会导致代码复杂性快速上升。美丽源于复杂性,但混乱永远不会消失。所以,我们必须学会掌握野兽!因此,让我们练习。
由转换运算符实现的转换称为用户定义转换。在将参数转换为函数参数的过程中,只能进行一次用户定义的转换。因此,即使shared_ptr
对其持有的指针使用了转换运算符,您仍然会得到错误。
因此,您必须从shared_ptr<texture_t>
声明转换运算符,但这是不可能的,因为转换运算符必须是成员函数。因此,一种选择可能是从shared_ptr
派生出来:
class texture_ptr_t
:public std::shared_ptr<texture_t> {
operator SDL_texture*() const{
return *get();
}
};
现在您必须仔细设计此类,该类可以通过派生到基数转换隐式转换为shared_ptr<texture_t>
……也许不是问题,或者以后会引起问题。