在下面的代码中,“main()”最后一行构造的对象似乎在表达式结束之前被销毁。析构函数在执行“<<”之前调用。这是应该的样子吗?
#include <string>
#include <sstream>
#include <iostream>
using std::string;
using std::ostringstream;
using std::cout;
class A : public ostringstream
{
public:
A () {}
virtual ~A ()
{
string s;
s = str();
cout << "from A: " << s << std::endl;
}
};
int
main ()
{
string s = "Hello";
A os;
os << s;
cout << os.str() << std::endl;
A() << "checking this";
}
Run Code Online (Sandbox Code Playgroud)
这是输出:
Hello
from A: 0x80495f7
from A: Hello
Run Code Online (Sandbox Code Playgroud)
这是 gdb 日志:
(gdb) b os.cxx : 18
Breakpoint 1 at 0x80492b1: file os.cxx, line 18. (2 locations)
(gdb) r
Starting program: /home/joe/sandbox/test/os
Hello
Breakpoint 1, ~A (this=0xbffff37c, __in_chrg=<value optimized out>, __vtt_parm=<value optimized out>) at os.cxx:18
18 cout << "from A: " << s << std::endl;
(gdb) p s.c_str ()
$1 = 0x804b45c "0x80495f7"
(gdb) p *s.c_str ()
$2 = 48 '0'
(gdb) c
Continuing.
from A: 0x80495f7
Breakpoint 1, ~A (this=0xbffff2bc, __in_chrg=<value optimized out>, __vtt_parm=<value optimized out>) at os.cxx:18
18 cout << "from A: " << s << std::endl;
(gdb) p s.c_str ()
$3 = 0x804b244 "Hello"
(gdb) p *s.c_str ()
$4 = 72 'H'
(gdb) c
Continuing.
from A: Hello
Program exited normally.
(gdb)
Run Code Online (Sandbox Code Playgroud)
A 直到完整语句执行后才会被删除。
您遇到的问题不是由 A 被删除并打印未初始化的数据引起的,而是由 r 值引用引起的。匿名实例只能通过值或 const 引用传递。
这意味着您的类将支持operator <<定义为成员函数,但不支持定义为全局函数。
为了展示这个尝试
struct A {
f()
};
void g(A & a) {
}
void foo() {
A a;
a.f();
g(a);
A().f();
g(A()); // This does not compile
}
Run Code Online (Sandbox Code Playgroud)
我实现了一个类似于您的 A 类的日志记录机制。它在 Visual Studio 6 中工作得很好,但在 Visual Studio 2005 中却不行。我通过使用委托而不是继承来修复它。
class A
{
ostringstream mystream;
public:
A () {}
virtual ~A ()
{
cout << "from A: " << mystream.str(); << std::endl;
}
ostream & stream()
{
return mystream;
}
};
int
main ()
{
string s = "Hello";
A os;
os.stream() << s;
A().stream() << "checking this";
}
Run Code Online (Sandbox Code Playgroud)
我假设您计划将其与日志记录和可能的宏一起使用。这就是我如何使用基于上面 A 的类。
#define TRACE_ERROR if (A::testLevel(A::Error) A(A::Error).stream()
#define TRACE_INFO if (A::testLevel(A::Info) A(A::Info).stream()
Run Code Online (Sandbox Code Playgroud)
然后在代码中
void foo()
{
int a = ..
std::string s = ..
TRACE_INFO << "Some information " << a << " message: " s;
}
Run Code Online (Sandbox Code Playgroud)