gpt4 book ai didi

c++ - ostrstream 将常量字符串解释为指针

转载 作者:太空狗 更新时间:2023-10-29 19:53:23 27 4
gpt4 key购买 nike

我在清理旧 C/C++ 应用程序的调试宏时遇到了这个问题:我们有一个继承自 ostrstream 的 Tracer 类(我知道它从 C++98 开始就被弃用了,但这个应用程序是在 1998 年编写的!)我们这样使用它:

Tracer() << "some" << " message" << " here";

现在如果链中的第一个值是一个常量字符串,调用ostrstream::str()的结果在 Tracer 上(在析构函数中完成,将结果插入队列)包含指向此字符串而不是文本的指针的十六进制表示。因此,上面的语句会产生类似 "0x401a37 message here" 的结果。 .旧宏不会发生这种情况,因为它们总是有一个长(线程 ID)作为现在已删除的第一个值。

用 gdb 进入它表明对于第一次插入,这调用了 operator<<(void const*)在 ostrstream 上,而随后的插入调用 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";
}

最佳答案

它以这种方式工作,因为 Tracer()是一个临时(右值),不能绑定(bind)到 operator<<(basic_ostream<...>&, 中的非常量引用.

但是,您可以调用成员函数,如 operator<<(void const*) ,因为它不需要左值。

成员函数然后返回对流对象的引用,可以用于调用下一个 operator<<在序列中。

以这种方式调用任何成员函数,例如Tracer() << leftTracer() << flush ,因此将引用“转换”为左值引用是非常安全的。

如果你碰巧有一个 C++11 兼容的编译器,标准库甚至包含一个 operator<<(basic_ostream<...>&&,这是为你做的。在这种情况下,您不再需要解决方法。

关于c++ - ostrstream 将常量字符串解释为指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14381311/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com