关于c ++:我应该使用转换运算符来处理我正在收尾的结构吗?

Should I use a conversion operator for the struct I'm wrapping up?

我正在打包一个C++类中与该结构相关的结构和函数。

1
2
3
4
5
6
7
class Surface
{
public:
   operator SDL_Surface* () { return this->surf_; } // good idea?
private:
   SDL_Surface* surf_;      
}

在这种情况下使用转换运算符是个好主意吗?还是会遇到问题?有其他选择吗?


这是个非常坏的主意。SDL_Surface*应该完全封装在类中,只能被SDL抽象的其他类访问。此外,你应该聪明地指向它,以确保它的安全销毁。


显性是好的,隐性是坏的。

标准库中的示例:要将std::string转换为char const*,必须调用c_str()。这样可以避免在不注意到涉及转换的情况下进行不神圣的操作,并且可以防止函数重载产生令人惊讶的结果。

任何经验法则都有例外。它不应该代替思考。但一般来说,要使转换隐式化,需要非常好的理由。


我建议使用std::shared_ptrSDL_FreeSurface作为自定义删除程序。


这要看情况而定。

如果您的表面是作为SDL-U表面的扩展,并且必须参与SDL-U表面所涉及的所有操作/功能,您可能希望有一种方法来公开"基本"元素。

但是,您最好返回一个引用或成本引用或两者都返回,而不是从类(表达式中具有不同间接级别的内容)返回指针:

1
2
3
4
5
6
7
8
class Surface
{
public:
   operator SDL_Surface& () { return *surf_; }
   operator const SDL_Surface& () const { return *surf_; }
private:
   SDL_Surface* surf_;      
}

(注:避免使用C-ish Javanese this->xxxx风格…)

如果你的表面只是另一件事,那就需要一个SDL_表面来处理,BAT拥有所有其他的应用程序域,而不应该有任何隐式转换可用。

注:在上面的注释中,我不做任何关于表面和SDL表面寿命或所有权的假设。我只是假设当两个对象必须参与任何操作时都存在。谁创造和摧毁了他们,在什么时候,按什么顺序,都是另一回事。请注意,使用引用计数智能指针并不能解决一般问题:除非您没有定义所有权方向,否则忘记指针而使用shared_ptr只是一种很好的方法,因为循环引用而导致内存泄漏。一个非常非常常见的错误,尤其是Java程序员。

故事的寓意:在决定如何创建和删除这些对象之前,一定要确定要对这些对象做什么,使用"指针"来控制它们,如果启用或不启用隐式转换,以及使用哪种转换。