在 C++11 中将结构作为输出参数传递
Passing structs as output parameters in C++11
在 C++11 中将结构作为输出传递的最佳实践是什么?
当所有权由外部函数维护时,应该在外部函数还是内部函数中创建结构?
而且,它应该是一个shared_ptr还是unique_ptr?
例如,假设我有一个复杂的结构,大致如下:
struct Error {
string Code;
string Message;
string Details;
string Command;
};
struct Response {
stringstream Data;
bool Success;
Error Error;
};
然后,从调用函数中,我想声明:
Response r;
getResponse( url, &r );
getResponse 应定义为:
getResponse( string, shared_ptr ); or
getResponse( string, unique_ptr );
另外,应该如何声明字符串和字符串流? 它们也应该被shared_ptr吗?
在这种情况下,getResponse 函数不希望响应完成后与响应有任何关系,响应本身的生存期应由调用方决定。
声明和填充结构的最佳做法是什么?
现代编译器非常擅长优化从函数返回值的方式,因此通常按值返回:
// Just return by value
Response getResponse(const std::string& url)
{
Response r;
// ...
return r;
}
好的,基于我无法复制数据的事实,在我的情况下,返回类型的响应将不起作用。
看来我有两个选择:
int getResponse( const std::string &url, shared_ptr<Response> )
或
unique_ptr<Response> getResponse( const std::string &url )
所以它变成了代码:
if( !getResponse( "http://...", response ) )
// report error
而不是
if( getResponse( "http://..." ) == nullptr )
// report error
就编码模式/最佳实践而言,哪个更可取?
我使用第二个的优点是,我可以检查结果而无需查看nullptr。
首先,Galik 的答案是正确的,只是按值返回。那么很明显,你的两种方法都是错误的。堆栈中有一个对象,该对象的生存期由编译器完美管理,您无法delete
该对象(或使用智能指针对其进行delete
)。
如果您对不按值返回有一些特殊的兴趣(也许该对象在紧密循环中重用,并且您希望重用字符串缓冲区......很可能不是这样,但请耐心等待),我建议您使用参数引用或指针:
void getResponse(std::string const& url, Response& resp);
void getResponse(std::string const& url, Response* resp);
第一个参数更清楚,因为第二个参数不是可选的,无需测试或担心它可能为 null。另一方面,某些编码约定需要第二种形式,因为从调用方的角度来看,函数将修改对象可能更清楚(在调用中getResponse(url, &response)
url
参数不会被修改,response
可能会(&
)。例如,谷歌的编码风格就是这种情况。 就个人而言,我更喜欢参考,但你知道...在罗马时...如果您的商店有政策,请遵循它。
为什么你应该在这里按值返回的一个略有不同的答案是你的结构的内容。 如果对象的内容移动成本低,则应按值返回。Move 语义将自动启动,因为编译器知道您返回的本地范围对象即将被销毁。
如果你的对象不是便宜的移动/复制,我会说通过引用/指针传递的经典建议仍然适用。 unique_ptr/shared_ptr 只有在解决对象所有权问题时才能发挥作用。 即。 我正在将此对象传递给一个函数,该函数现在拥有它。 如果所有权没有被改变,请使用通过引用和指针传递的经典建议。
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 使用指向成员的指针将成员函数作为参数传递
- 如何将参数传递给正在使用模板的类
- 是否有C++编译器选项允许激进地删除所有函数调用,并将参数传递给具有空体的函数
- 修改函数中的指针(将另一个指针作为参数传递)
- 如何将部分流作为参数传递
- 我正在开发服务器,ip作为参数传递不起作用
- 将成员函数指针作为参数传递给模板方法
- 如何在C++中将迭代器作为函数参数传递
- 将附加参数传递给使用 beast::bind_front_handler 调用的函数
- 如何将一个类的函数作为另一个类的另一个函数的参数传递
- 将参数传递为"const"的奇怪效果
- 如何在 c++ 中将函数作为参数传递?
- 在 C++ 中将非指定类型作为参数传递的最佳方法?
- 使用引用与指针将数组作为参数传递
- 如何将成员函数作为回调参数传递给需要"typedef-ed"自由函数指针的函数?
- 将std::vector作为输入/输出引用参数传递时丢失了一些数据
- 在 C++11 中将结构作为输出参数传递
- Linux将连续输出作为命令行参数传递
- 如何传递Blitz++子数组作为过程的输入/输出参数