My String类提供了一个操作符char *重载,允许您将字符串传递给C函数。
不幸的是,我的一位同事无意中发现了一个错误。
他实际上有以下代码。
StringT str;
// Some code.
delete str;
反正是否有阻止删除将字符串对象强制转换为char *以防止将来出现这样的错误? std::string
通过不提供char运算符重载来解决这个问题,但理想情况下,我希望保持重载但阻止该删除工作。
答案 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
非指针的人可能会滥用你的课程。
答案 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;
}