将std :: shared_ptr隐式转换为指针类型

时间:2019-05-11 14:28:22

标签: c++ sdl

我有一些包装器类,它们将包装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_ttexture_ptr_t隐式转换为它。

我在课堂上尝试实现这些运算符:

operator SDL_Texture *(void);
operator const SDL_Texture *(void) const;

但是我仍然遇到no viable conversion from texture_ptr_t to SDL_Texture *错误。有人可以为我指出正确的方向吗?

2 个答案:

答案 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>……也许不是问题,或者以后会引起问题。