停止对operator delete的隐式强制转换

时间:2010-01-26 09:27:30

标签: c++ memory-management implicit-cast

My String类提供了一个操作符char *重载,允许您将字符串传递给C函数。

不幸的是,我的一位同事无意中发现了一个错误。

他实际上有以下代码。

StringT str;
// Some code.
delete str;

反正是否有阻止删除将字符串对象强制转换为char *以防止将来出现这样的错误? std::string通过不提供char运算符重载来解决这个问题,但理想情况下,我希望保持重载但阻止该删除工作。

5 个答案:

答案 0 :(得分:8)

是。通过声明(但不定义!)operator char const volatile*来提供两个隐式强制转换。当您将StringT传递给C字符串函数时,重载决策仍会选择原始operator char const*(完全匹配)。但delete str;现在变得含糊不清。

声明可以是私有的,因此如果以某种方式选择它将是编译时错误。预期的歧义发生在重载解析之前 - private仅用于捕获极少数情况下以某种方式选择volatile重载。

答案 1 :(得分:5)

  

无论如何都要阻止删除将字符串对象强制转换为char * ...?

是的:回避隐式投射操作员。这已经被传播了至少十年了。相信它,你将过上更幸福的生活。

答案 2 :(得分:4)

信不信由你,有一个原因是std :: string不提供隐式转换,c_str()函数不是为了激怒你而创建的。提供隐含的转换,让你自己开启一个充满模糊和痛苦的世界。

答案 3 :(得分:0)

有争议的意见时间:如果有人编写了遭受此“错误”的代码,他们应该被咬伤

用你的问题来解释:

  

如何阻止人们使用我的枪支射击自己?

你做不到。我不同意@sbi的意见,并说你的超载很好。如果这会导致某人的代码出现问题,那是因为有人不了解C ++而不应该对其进行编码。

你需要担心的问题比那些不能很好地理解语言而不知道delete非指针的人可能会滥用你的课程。

警告:我对C ++比较陌生,并没有看到一些更加灰白的老兵的恐怖。有些模糊不清的样本可能会让我相信我的邪恶方式。然而,这不是它。

答案 4 :(得分:0)

struct Dummy {};
class StringT {
public:
    // ........
    operator char*() { /*...*/ }
    operator const char*() const { /*...*/ }

    operator const Dummy* () const { return 0; }
    operator Dummy* () { return 0; }
};

/// ...
void g(const char * ) { /*...*/ }

int main() {

    StringT str;
    g(str); // OK
    delete str; //error C2440: 'delete' : cannot convert from 'StringT' to 'void *'
    return 0;
}