这是一个简单的类和简单的测试函数:
#include <queue>
#include <string>
namespace {
using namespace std;
}
class NameStream {
queue<string> stream;
public:
string operator * () { return stream.front(); }
NameStream &operator ++(int) { stream.pop(); return *this; }
NameStream &operator ++() { stream.pop(); return *this; }
NameStream &operator <<(string name) { stream.push(name); }
operator bool() { return !stream.empty(); }
};
inline void nameStreamTest() {
NameStream &stream = *new NameStream;
stream << "hi" << "hey" << "hoy";
while (stream) {
printf("%s\n", (*stream++).c_str());
}
}
它属于
NameStream &operator <<(string name) { stream.push(name); }
在队列的推送过程中,这是我的代码之外的堆栈:
#0 0x000b5079 in std::deque<std::string, std::allocator<std::string> >::push_back at stl_deque.h:1055
#1 0x000b50f2 in std::queue<std::string, std::deque<std::string, std::allocator<std::string> > >::push at stl_queue.h:204
#2 0x000b511c in NameStream::operator<< at NameStream.h:24
#3 0x000b520f in nameStreamTest at NameStream.h:32
我的经历在这种情况下失败了。我做错了什么?
P.S:
NameStream &stream = *new NameStream;
用于清除
的位置stream
对象在地址(偏移?)0x7d(!)导致相同的异常。
答案 0 :(得分:6)
在函数末尾添加一个return语句。
NameStream &operator <<(string name) { stream.push(name); return *this; }
添加:不返回有效的引用/值(如果需要)将导致UB,这将导致隐藏的崩溃或通常难以调试的错误行为(如您的情况)。因此,如果生成任何编译器警告,请永远不要忽略它。
答案 1 :(得分:2)
由于后缀运算符++
的优先级高于运算符*
,因此失败,所以当执行循环的最后一次迭代时,首先从队列pop
开始,然后尝试执行front
队列为空的时间。要解决这个问题,最简单的方法是将其分为两个语句:
while (stream) {
printf("%s\n", (*stream).c_str());
stream++;
}
答案 2 :(得分:0)
它属于
NameStream &operator <<(string name) { stream.push(name); }
您不会通过链接*this
调用返回operator<<()
...,第二个和第三个调用没有有效的对象地址可供使用。
答案 3 :(得分:0)
您在代码中遇到了许多问题。
operator<<
中缺少返回(正如iammilind和其他人所指出的那样)导致您观察到的运行时错误。它可以纠正如下:
NameStream &operator <<(string name) { stream.push(name); return *this; }
另一个问题是由于你的while循环体中的调用顺序是:
因此,在最后一次迭代中,您首先在pop()
中operator++(int)
然后尝试在空front()
中调用operator*()
,这将导致运行时错误。
解决问题的最简单方法是重写while循环,如下所示。
while (stream) {
printf("%s\n", (*stream).c_str());
++stream;
}
内存泄漏。您使用new
调用分配NameStream对象,但从不调用delete
。一个简单的解决方案是在堆栈上分配您的流对象:
NameStream stream;