我在 C++ 类中包装了一个结构和与该结构相关的函数。
class Surface
{
public:
operator SDL_Surface* () { return this->surf_; } // good idea?
private:
SDL_Surface* surf_;
}
在这种情况下使用转换运算符是个好主意吗?还是我会遇到问题?有什么选择吗?
我在 C++ 类中包装了一个结构和与该结构相关的函数。
class Surface
{
public:
operator SDL_Surface* () { return this->surf_; } // good idea?
private:
SDL_Surface* surf_;
}
在这种情况下使用转换运算符是个好主意吗?还是我会遇到问题?有什么选择吗?
这是一个非常糟糕的主意。SDL_Surface*
应该完全封装在类中,只能由属于您的 SDL 抽象一部分的其他类访问。此外,您应该聪明地指向它以确保它被安全销毁。
我建议使用std::shared_ptr<SDL_Surface>
withSDL_FreeSurface
作为自定义删除器。
显式是好的,内式是坏的。
标准库中的示例:要将 a 转换std::string
为char const*
,您必须调用c_str()
. 这使您免于在没有注意到涉及转换的情况下做不圣洁的事情,并且可以防止函数重载导致令人惊讶的结果。
作为任何经验法则,这条规则有例外。它不应该代替思考。但一般来说,隐式转换需要非常充分的理由。
这取决于.
如果您的表面旨在作为 SDL_Surface 的扩展,并且必须参与 SDL_Surface 涉及的所有操作/功能,您可能希望有一种方法来公开“基本”元素。
但是,与其从类返回指针(在表达式中具有不同间接级别的东西),您可能最好返回引用或成本引用或两者兼而有之:
class Surface
{
public:
operator SDL_Surface& () { return *surf_; }
operator const SDL_Surface& () const { return *surf_; }
private:
SDL_Surface* surf_;
}
(注意:避免使用 C#-ish Javanesethis->xxxx
风格......)
如果您的 Surface只是另一件事,需要一个 SDL_Surface 才能使用,那么 bat 拥有所有其他应用程序域,那么应该没有可用的隐式转换。
注意:
在上面的注释中,我没有对 Surface 和 SDL_Surface 的生命周期或所有权做任何假设。我只是假设这两个对象在必须参与任何操作时都存在。谁创造和摧毁它们,以什么顺序和时间,都是另一回事。请注意,引用计数智能指针的使用并不能解决一般问题:除非您没有定义所有权方向,否则忘记支持的指针shared_ptr
只是由于循环引用而导致内存泄漏的好方法。一个非常常见的错误,尤其是来自 Java 程序员的错误。
故事的寓意:在决定如何创建和删除它们之前,确定你想对这些对象做什么,“指针”的巫王用来保存它们,是否启用或不启用隐式转换以及哪个。