C++:局部变量通过引用传递给 class with pointer 成员

C++: local variable passed by reference to the class with pointer member

我预计以下代码会失败(在 main 函数中),但它有效:

class Response {
public:
    Response() {}

    void displayInfo() {
        cout << "Hello!" << endl;
    }
};

class HttpClient
{
public:
    HttpClient(Response& response) : m_response(&response) {
        m_response = &response;
    }

    Response* getResponse() {
        return m_response;
    }

private:

    Response *m_response;
};


HttpClient* createClient()
{
    Response response;
    HttpClient *clnt = new HttpClient(response);
    clnt->getResponse()->displayInfo();
    return clnt;
}


int main()
{
    HttpClient* client = createClient();

    // ------------------------------------------
    // I expect getResponse()->displayInfo() to fail, since "response" object
    // passed as argument to HttpClient (in createClient function) goes out of the scope and should be deleted.

    client->getResponse()->displayInfo();
}

所以我在 createClient 函数中创建了局部变量 response。 然后这个局部变量作为构造函数参数(引用)传递给 HttpClient。

此参数已分配给成员Response *m_response

据我了解,m_response 引用了 response 局部变量。

但是当response局部变量超出范围时,我仍然可以通过m_response访问它(m_response对象的调用方法)。

我希望 m_response 应该引用一些垃圾,因为 response 超出了范围。

为什么有效?

Why does it work?

它能工作基本上是因为实现允许它,可能是因为它还没有 reused/recycled 局部变量正在使用的内存。这里的行为是未定义的,所以任何事情都可能发生。它可以这样工作,但不是必须的。

此外,当您访问指向现在已经消失的内存的指针时,我最好定义您所说的 "fail" 的意思。通常,C++ 标准中有强和弱 "failure" 保证。强失败保证是 well-defined(例如,抛出异常,return 错误代码)。但是有很多弱故障最终会导致未定义的行为,您在编写代码时必须小心。许多指针操作的失败最终都是未定义的行为,所以如果你想要更强的失败保证,我会切换到智能指针等。