我有一些用C风格编写的C++代码。
由于某些原因,我不能使用C++的字符串和IO库,所以在处理字符串时,我应该只使用像sprintf
、itoa
等函数。
我想要用以下代码替换需要临时缓冲区的C风格: char buf[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*
变量不同,它可能不是很明显。
有没有办法使这些类更加安全?
更新:为什么不使用std::string、boost::lexical_cast、boost::format等:
代码应该在编译时使用-fno-except(禁用C++异常-无throw
,无堆栈展开)时正常工作。同时,它应该在低内存条件下继续工作。
std::string
和流使用堆分配的内存,而且至少会抛出bad_alloc
异常。
当我们没有可用的堆内存时,通常我们仍然有一些千字节大小的堆栈(例如向用户写入我们已经用完内存,然后进行适当的清理)。