【问题标题】:C++: local variable passed by reference to the class with pointer member [duplicate]C ++:通过引用传递给具有指针成员的类的局部变量[重复]
【发布时间】:2018-03-10 19:31:31
【问题描述】:

我预计以下代码会失败(在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 超出了范围。

为什么会起作用?

【问题讨论】:

  • 未定义行为未定义:P
  • 未定义的行为总是按预期工作。
  • C++ 将确保您的代码正确的大量负担交给您(程序员) - 没有自动检查(原始)指针所指的内存是否仍然包含有效对象
  • @nullqube 你在说什么?这里不涉及引用计数,createClient 中使用的 Response 对象显然超出了范围
  • 是的,我是对的,看看这个:stackoverflow.com/questions/3097593/…

标签: c++ pointers reference pass-by-reference


【解决方案1】:

为什么会起作用?

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

另外,当您访问指向现已消失的内存的指针时,我会更好地定义“失败”的含义。一般来说,C++ 标准中有强弱的“失败”保证。强故障保证是明确定义的(例如,抛出异常、返回错误代码)。但是有很多弱故障最终会导致未定义的行为,您在编写代码时必须小心。很多指针操作的失败最终都是未定义的行为,所以如果你想要一个更强的失败保证,我会切换到智能指针等。

【讨论】:

  • 好吧,这不是“正确的代码”吧?
  • 取决于“正确代码”的含义。该程序的语法是正确的,但它的内存使用和期望却不正确。
  • @Teimuraz 不,它不是正确的代码。响应对象超出范围。您获得“正确”结果的事实是未定义行为的不幸副作用(它偶然“起作用”)。 HttpClient 构造函数应该制作了 response 的深层副本,如果他们打算以这种方式 createClient
猜你喜欢
  • 2022-01-16
  • 1970-01-01
  • 1970-01-01
  • 2016-08-26
  • 2014-10-12
  • 2021-11-11
  • 1970-01-01
  • 1970-01-01
  • 2014-10-03
相关资源
最近更新 更多