C++在销毁后使用引用对象

C++在销毁后使用引用对象,c++,pointers,constructor,reference,destructor,C++,Pointers,Constructor,Reference,Destructor,我尝试了一些关于引用和指针的东西,发现了一些我根本不懂的东西 这是我的密码: #include <iostream> using namespace std; class A { public: A() { cout << "con\n"; } ~A() { cout << "des\n"; } void f() { cout << "bla" << endl; } }; A &crea

我尝试了一些关于引用和指针的东西,发现了一些我根本不懂的东西

这是我的密码:

#include <iostream>

using namespace std;

class A
{
    public:
     A() { cout << "con\n"; }
    ~A() { cout << "des\n"; }

    void f() { cout << "bla" << endl; }
};

A &createA()
{
    A *a = nullptr;

    {
        A b;
        a = &b;
        cout << *&a << endl;
    }

    return *a;
}

int main()
{
    A &b(createA());
    cout << &b << endl;

    b.f();

    system("pause");

    return 0;
}

正如您所看到的,成员函数f仍然被调用,即使在对象本身被销毁之后也是如此。为什么?我认为应该有一些错误,但是函数f确实被调用,并且它的事件做的一切都正确,为什么?

编译器警告在这里是不言自明的:

main.cpp: In function 'A& createA()':
main.cpp:24:13: warning: function may return address of local variable [-Wreturn-local-addr]
     return *a;
             ^
main.cpp:19:11: note: declared here
         A b;
           ^

编译器警告在这里是不言自明的:

main.cpp: In function 'A& createA()':
main.cpp:24:13: warning: function may return address of local variable [-Wreturn-local-addr]
     return *a;
             ^
main.cpp:19:11: note: declared here
         A b;
           ^

这是未定义的行为,简单明了


当您参与UB时,编译器不需要警告您,但可以假设您不会这样做,并且如果您无论如何都这样做,您无法保证会发生什么。程序完全无效,任何事情都可能发生。

这是未定义的行为,简单明了


当您参与UB时,编译器不需要警告您,但可以假设您不会这样做,并且如果您无论如何都这样做,您无法保证会发生什么。程序完全无效,任何事情都可能发生。

未定义的行为不能保证错误或崩溃。未定义的行为意味着将发生的事情可能是任何事情,甚至是看起来合理的事情。代码是错误的,它能产生的任何东西都不需要考虑。OP应该明确阅读链接副本中的公认答案-这是一个可爱的类比。未定义的行为不保证错误或崩溃。未定义的行为意味着将发生的事情可以是任何事情,甚至看起来合理的事情。这段代码是错误的,它能产生的任何东西都不需要考虑。OP应该明确阅读链接副本中接受的答案-这是一个很好的类比