1

我的 String 类提供了一个运算符 char* 重载,允许您将字符串传递给 C 函数。

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

他实际上有以下代码。

StringT str;
// Some code.
delete str;

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

4

5 回答 5

8

Yes. Provide TWO implicit casts, by declaring (but not defining!) operator char const volatile*. When you're passing your StringT to a C string function, overload resolution will still select your original operator char const* (exact match). But delete str; now becomes ambiguous.

The declaration can be private, so if it would somehow be selected will be a compile-time error. The intended ambiguity occurs before overload resolution - the private only serves to catch the exceedingly rare cases where the volatile overload would be selected somehow.

于 2010-01-26T10:00:07.310 回答
5

有没有办法阻止 delete 将字符串对象转换为 char* ...?

是的:回避隐式转换运算符。这已经被宣扬了至少十年。相信它,你会过上更幸福的生活。

于 2010-01-26T09:30:34.287 回答
4

信不信由你,std::string 不提供隐式转换是有原因的,创建 c_str() 函数并不是为了激怒你。提供隐含的转换,你就会向一个充满歧义和痛苦的世界敞开大门。

于 2010-01-26T09:34:53.253 回答
0

有争议的意见时间:如果有人编写的代码有这个“错误”,他们应该被咬

解释你的问题:

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

你不能。我不同意@sbi的意见,并说你的超载很好。如果这导致某人的代码出现问题,那是因为某人不了解 C++,不应该编写它。

You have bigger problems to worry about than whether or not someone who doesn't understand the language well enough to know not to delete things that aren't pointers can abuse your class.

Caveat: I am relatively new to C++, and have not seen the horrors of some more grizzled veterans. It is possible that a sample of particularly bad ambiguity might convince me of my evil ways. This, however, is not it.

于 2010-01-26T09:37:03.813 回答
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;
}
于 2010-01-26T10:25:45.353 回答