给定
#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;
}
输出应该是“<[]>”。然而,它是“<[]]”。
- 我错了吗?如果是,为什么?
- 如果不是,那么这种行为的潜在原因是什么?
最佳答案
实际上,由于以下原因,您的代码的行为是未定义的:
return this->operator std::string().c_str();
您正在临时调用 c_str()
,稍后使用结果。
您看到的是未定义行为的有效表现。
现在,如果您想知道引擎盖下究竟发生了什么,您可以将 main()
的最后一行修改为:
cout << (const void*)C2() << ' ' << (const void*)B2() << endl;
如果这样做,您可能会看到同一个地址被打印两次(在这两种情况下都是悬空指针)。这是我电脑上发生的情况,我怀疑你的电脑上也会发生这种情况。 当然,由于行为是未定义的,这只是许多可能的表现形式之一。
关于c++ - 虚函数的反直觉行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8533239/