我有一些用 C 风格编写的 C++ 代码。
由于某些原因,我不能使用 C++ 字符串和 IO 库,因此对于字符串处理,我应该只使用像 sprintf
这样的函数。 , itoa
等
我想替换需要临时缓冲区的 C 风格 字符缓冲区[12]; itoa(x, buf, 16); set_some_text(buf);
通过以下代码
class i2a
{
public:
explicit i2a(int value) { ::sprintf(buf, "%d", value); }
operator const char* () const { return buf; }
private:
char buf[12];
};
// usage:
set_some_text(i2a(x));
(可以为 char<->wchar_t
转换等编写此类类)
我看到一些这样的类会很危险的情况: 例如,一个人可以写
const char* someMeaningfulName = i2a(x);
// the right code should be i2a someMeaningfulName(x); or i2a someMeaningfulName = i2a(x);
set_some_text(someMeaningfulName);
在更复杂的情况下,接受文本的函数不会复制它,但会在某处保存指向它的指针。例如可能是
class Foo { .... const char* p; };
Foo f(const char* text) { ... foo.p = text; return foo; }
与const char*
不同,它可能真的不明显变量。
有没有办法让这些类更安全?
Upd:为什么不是 std::string、boost::lexical_cast、boost::format 等:
当使用 -fno-except 编译时,代码应该可以工作(禁用 C++ 异常 - 没有 throw
,没有堆栈展开)。它还应该在内存不足的情况下继续工作。
std::string
, streams 使用堆分配的内存并且至少抛出 bad_alloc
.
当我们没有可用的堆内存时,通常我们还有几千字节的堆栈(例如,写给用户我们的内存不足,然后进行适当的清理)。
最佳答案
ATL和MFC的字符串转换宏也是这样写的。像 i2a(x)
一样直接调用构造函数将创建一个临时对象,该对象将一直存在,直到传递给它的函数完成为止。所以在这里:do_some(i2a(x))
,临时对象会一直存在直到do_some()
完成。
请参阅此 msdn document 的示例部分(示例 2)
这里,
const char* someMeaningfulName = i2a(x);
set_some_text(someMeaningfulName);
这是行不通的,因为临时对象将在第一个语句本身时被释放。 someMeaningfulName
将是垃圾。如果你觉得缺乏安全感,我只能说:
That's how Microsoft does it!
关于c++ - C 字符串函数的包装器类有问题吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6939239/