c++ - 虚函数的反直觉行为

标签 c++

给定

#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;
}

输出应该是“<[]>”。然而,它是“<[]]”。

  1. 我错了吗?如果是,为什么?
  2. 如果不是,那么这种行为的潜在原因是什么?

最佳答案

实际上,由于以下原因,您的代码的行为是未定义的:

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/

相关文章:

c++ - 仅通过指针转换创建可互换的类类型,而无需分配任何新对象?

c++ - 模板函数的模板参数

c++ - QThread moveToThread 不起作用

c++ - "Cannot"移动指针

c++ - 文件数据读取到 map ,但 map::find() 不起作用

c++ - 允许销毁 std::fstream 是否会关闭相关文件?

c++ - QCompleter 运行时崩溃

c++ - 在 C++ 中转换指针

c++ - 删除是一个成员函数?私有(private)的析构函数不会被删除调用吗?

关于在 char 中放置一个小整数的 C++ 信息