c++ - C 字符串函数的包装器类有问题吗?

标签 c++

我有一些用 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/

相关文章:

c++ - 在 Linux 中获取键盘键码键

C++:直接使用函数返回 shared_ptr 的值是个坏主意吗?

java - 通过 C++/Java 进行音频编辑

c++ - 字符串与特殊字符的匹配

c++ - 您如何合法地对舍入 double 执行 mod 运算符?

C++ Builder 字符数组寻址

c++ - 我可以用传递给 C++ 函数的形式参数创建 union 吗?

c++ - Boost::variant 的多态 setter

c++ - 错误 : expected function body after function declarator

c++ - 初始化C结构的双花括号是什么意思?