特定
#include <string>
#include <iostream>
struct A {
virtual operator std::string() const { return "A"; }
virtual operator const char *() const { return this->operator std::string().c_str(); }
};
struct B1 : public A {
virtual operator std::string() const { return "<"; }
};
struct B2 {
B2() { }
virtual ~B2() { }
virtual operator std::string() const { return ">"; }
virtual operator const char *() const { return this->operator std::string().c_str(); }
};
struct C1 : public A {
C1() { }
virtual ~C1() { }
virtual operator std::string() const { return "["; }
};
struct C2 {
C2() { }
virtual ~C2() { }
virtual operator std::string() const { return "]"; }
virtual operator const char *() const { return this->operator std::string().c_str(); }
};
int main() {
using namespace std;
cout << B1() << endl;
cout << C1();
cout << C2() << B2() << endl;
}
Run Code Online (Sandbox Code Playgroud)
输出应为"<[]>".但是,它是"<[]]".
实际上,由于以下原因,代码的行为未定义:
return this->operator std::string().c_str();
Run Code Online (Sandbox Code Playgroud)
你正在呼叫c_str()一个临时的,并在以后使用结果.
您所看到的是未定义行为的有效表现.
现在,如果你对引擎盖下实际发生的事情感到好奇,你可以修改最后一行main()来阅读:
cout << (const void*)C2() << ' ' << (const void*)B2() << endl;
Run Code Online (Sandbox Code Playgroud)
如果你这样做,你可能会看到相同的地址被打印两次(在两种情况下都是悬空指针).这就是我的电脑上发生的事情,我怀疑你的电脑会发生什么.当然,由于行为未定义,这只是许多人的一种可能的表现形式.