Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/133.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何实现C++;方法创建新对象并返回对该对象的引用 我有一个C++验证代理类实例,用下面的方法。此方法创建一个响应对象,然后使用状态更新该对象,然后返回。由于响应对象的内部结构,无法复制它(即,我不能简单地按值返回)_C++_Reference_Static - Fatal编程技术网

如何实现C++;方法创建新对象并返回对该对象的引用 我有一个C++验证代理类实例,用下面的方法。此方法创建一个响应对象,然后使用状态更新该对象,然后返回。由于响应对象的内部结构,无法复制它(即,我不能简单地按值返回)

如何实现C++;方法创建新对象并返回对该对象的引用 我有一个C++验证代理类实例,用下面的方法。此方法创建一个响应对象,然后使用状态更新该对象,然后返回。由于响应对象的内部结构,无法复制它(即,我不能简单地按值返回),c++,reference,static,C++,Reference,Static,在AuthenticationProxy类中,此方法可能会发生许多调用,因此在此处使用静态变量并不理想。有人能提出一个解决方案,返回函数退出时未销毁的引用吗?谢谢 在我的研究中,最接近我的是最佳实践页面,上面提到“通过引用返回,而不是通过创建大型对象返回值”,但我还没有找到一个例子!所有示例都是针对传入然后返回的引用,或者针对int&style引用,而不是在函数本身中创建对象实例的引用 我认为解决方案可能存在于将函数return response作为一个值,但在调用代码中使用const变量来捕获

在AuthenticationProxy类中,此方法可能会发生许多调用,因此在此处使用静态变量并不理想。有人能提出一个解决方案,返回函数退出时未销毁的引用吗?谢谢

在我的研究中,最接近我的是最佳实践页面,上面提到“通过引用返回,而不是通过创建大型对象返回值”,但我还没有找到一个例子!所有示例都是针对传入然后返回的引用,或者针对int&style引用,而不是在函数本身中创建对象实例的引用

我认为解决方案可能存在于将函数return response作为一个值,但在调用代码中使用const变量来捕获它。不确定这是否只适用于int-我发现的所有示例都使用基本类型。非常感谢您的帮助

由于响应对象的内部结构,无法复制它(即,我不能简单地按值返回)

您正在描述一个在C++03中存在的问题,但它已经不存在了

以旧的
std::fstream

为例,基本上,在它的内部*,有一个文件描述符/句柄,用于对文件进行读/写操作。
因为C++的性质和设计, fStuts析构函数关闭了文件句柄,以清除对象并防止句柄泄漏。 由于
fstream
对象的内部结构,无法通过值返回它。按值返回它意味着以某种方式防止析构函数关闭该文件句柄,或使复制构造函数以某种方式复制该句柄。跨平台解决方案即使不是不可能,也是极其困难的。更不用说复制内部缓冲区是完全错误的

因此,在C++11之前,您无法按值返回
fstream

然后移动语义学被发明了

在C++11中,您可以只移动对象而不是复制它。在
fstream
示例中,move构造函数复制文件句柄,同时使原始文件句柄指针无效。原始对象析构函数将检查原始文件句柄,查看它是否无效,并跳过关闭它

这是解决您问题的惯用方法。虽然不能复制对象,但可以为其实现移动语义。对象的内部将被移动到返回值,而原始对象在某种程度上保持“空”

关于移动语义的良好解释可以在以下答案中找到:

如果该解决方案不可行,则在动态内存存储(“堆”)中声明该对象,并通过某个智能指针返回该对象

<如何实现创建新对象的C++方法,并返回 参考它

即使你能做到,也不要这样做


<文件>句柄可以存储在<代码>流式文件< /COD>对象中,我简单地描述了这个问题。

< P> C++中有三个存储类。静态、自动和动态

退出作用域时,自动对象将被销毁,因此不能返回对局部自动变量的引用

您可以返回对static的引用,但正如您所说的,它不适合您

剩下的唯一选项是动态。但是,动态对象必须以某种方式销毁,当您返回对动态创建的对象的引用时,调用者不清楚是否应该处理它的销毁。因此,这在技术上是可能的,但内存管理†没有好的解决方案。此外,动态分配可能会很昂贵

†如果您坚持要返回推荐信,则不会。但是如果您返回一个
std::unique_ptr
,这个问题就会消失

那么,让我们重新讨论自动变量选项。我说过,您不能返回对本地自动变量的引用。从更高的范围返回对自动变量的引用是完全可以的。如何访问这样的变量?使用参考当然

const Response& AuthenticatingProxy::Get(const std::string& host,
                                  const std::string& path,
                                  const http_headers& headers,
                                  Response& response)
{
  // do the HTTP call, and set response's state here
  return response; // might as well return void because caller already has a reference
}
当动态分配过于昂贵且编译器不支持移动语义时,这是一个典型的解决方案。在这个解决方案中,函数中实际上没有创建对象。它只是为调用者创建的对象设置数据。对象实际上可以有任何存储类型,这无关紧要


然而,最好的解决方案是按值返回。您说
响应
不可复制。但从C++11开始,只要类型是可移动的,就不能阻止按值返回它。甚至这一举措也被大多数编译器忽略了

Response response;
// do stuff to response
return response;

多亏了你的提示,我找到了一个答案

(尽管如其他人所述,这会给调用者留下内存管理的问题。这很适合我的需要。)

本页对此进行了说明:

以下是我的新方法声明:-

const Response* AuthenticatingProxy::Get(const std::string& host,
                                  const std::string& path,
                                  const http_headers& headers)
{
  auto && response = new Response;
  // do stuff to response
  return std::move(response);
}
因此,我返回一个指针,但以上述方式使用std::move和auto会返回一个可以在调用代码中管理的指针

编辑:-

好的,根据反馈,我现在在authenticationproxy.cpp中有以下内容:-

std::unique_ptr<Response> AuthenticatingProxy::Get(const std::string& host,
                                  const std::string& path,
                                  const http_headers& headers)
{
  Response* response = new Response;
  // do call and fill out the response
  return std::unique_ptr<Response>(response);
}
std::unique\u ptr authenticationproxy::Get(const std::string&host,
常量std::字符串和路径,
const http_头和头)
{
响应*响应=新响应;
//一定要打电话并填写回复
返回std::unique_ptr(响应);
}
我的中间连接类正在执行以下操作:-

std::unique_ptr<Response> Connection::getDocument(const std::string& uri) {
  return Connection::_proxy.Get(_serverUrl, "/v1/documents?uri=" + uri); 
}
    // MUST keep local reference to unique_ptr for this to work!!!
    const std::unique_ptr<Response> rp = connection->getDocument(uri); 
    Response* response = rp.get();
    ...
    std::cout << "This is JSON doc " << uri << ": " << std::endl << response->Json() << std::endl;
std::唯一的ptr连接
    // MUST keep local reference to unique_ptr for this to work!!!
    const std::unique_ptr<Response> rp = connection->getDocument(uri); 
    Response* response = rp.get();
    ...
    std::cout << "This is JSON doc " << uri << ": " << std::endl << response->Json() << std::endl;