【发布时间】:2013-01-01 02:58:14
【问题描述】:
我在清理旧 C/C++ 应用程序的调试宏时遇到了这个问题:我们有一个 Tracer 类继承自 ostrstream(我知道它自 C++98 以来已被弃用,但此应用程序是用1998!)我们这样使用:
Tracer() << "some" << " message" << " here";
现在,如果链中的第一个值是上面的常量字符串,则在 Tracer 上调用 ostrstream::str() 的结果(在析构函数中完成,将结果插入队列)包含指针的十六进制表示到这个字符串而不是文本。因此上面的语句会产生类似"0x401a37 message here" 的东西。旧的宏不会出现这种情况,因为它们总是将长(线程 ID)作为第一个值,现在已被删除。
使用 gdb 进入它表明,对于第一次插入,这会在 ostrstream 上调用 operator<<(void const*),而随后的插入会调用 operator<< <...>(basic_ostream<...>&, char const*)(为了便于阅读而删除了模板)。
有人可以解释这种行为吗?什么是解决这个问题的干净方法?我找到了一个简单的解决方法,它使用<< left 作为第一个参数 - 这安全吗?有没有更好的方法来做到这一点?
这是一个最小化的例子:
#include <strstream>
#include <iostream>
using namespace std;
class Trace : public ostrstream {
public:
Trace();
virtual ~Trace();
};
Trace::Trace() : ostrstream() {}
Trace::~Trace() {
static_cast< ostrstream& >(*this) <<ends;
char * text = ostrstream::str();
cout << "MESSAGE: "<< text <<endl;
delete[] text;
}
int main(){
Trace() << "some" << " text" << " here";
Trace() << left << "some" << " text" << " here";
Trace() << 123 << " text" << " here";
}
【问题讨论】: