Lea*_*Cpp 4 c++ return return-value-optimization c++11
下面是具有各种返回语句的代码,并且所有代码都运行良好.编译器会抛出fun_ret_obj1的警告
Test.cpp:在函数'myClass&fun_ret_obj1()'中:Test.cpp:45:警告:返回对局部变量'myObj'的引用
但仍然输出似乎很好.是机会吗?以下任何退货声明是否有任何捕获?
解释会非常有用,谢谢
#include <iostream>
using namespace std;
class myClass {
public:
int a ;
myClass()
{
a = 10;
}
};
myClass& fun_ret_add()
{
myClass *ptr = new myClass();
return *ptr;
}
myClass* fun_ret_ptr()
{
myClass *ptr = new myClass();
return ptr ;
}
myClass fun_ret_obj()
{
myClass myObj;
return myObj;
}
myClass& fun_ret_obj1()
{
myClass myObj;
return myObj;
}
int main()
{
myClass obj,obj1;
std::cout <<"In Main \n";
myClass *a = fun_ret_ptr();
std::cout<<a->a<<"\n";
myClass &b = fun_ret_add();
std::cout<<b.a<<"\n";
myClass c = fun_ret_obj();
std::cout<<c.a<<"\n";
myClass d = fun_ret_obj1();
std::cout<<d.a<<"\n";
}
Run Code Online (Sandbox Code Playgroud)
Ric*_*ges 13
第一个是内存泄漏:
myClass& fun_ret_add()
{
myClass *ptr = new myClass();
return *ptr;
}
Run Code Online (Sandbox Code Playgroud)
第二个返回一个原始指针(邪恶 - 返回一个std :: unique_ptr)
myClass* fun_ret_ptr()
{
myClass *ptr = new myClass();
return ptr ;
}
Run Code Online (Sandbox Code Playgroud)
第三个是完美的 - 返回一个副本,几乎总是被省略.在c ++ 17中,它保证被省略.这是有效和安全的.
myClass fun_ret_obj()
{
myClass myObj;
return myObj;
}
Run Code Online (Sandbox Code Playgroud)
更新
在c ++ 17中,您可以通过这种方式保证副本的省略:
myClass fun_ret_obj()
{
return myClass{};
}
Run Code Online (Sandbox Code Playgroud)
更新结束
第四个是未定义的行为.返回对不存在的对象的引用.永远不要这样做.
myClass& fun_ret_obj1()
{
myClass myObj;
return myObj;
}
Run Code Online (Sandbox Code Playgroud)
确实,在第一个示例中,如果调用者知道myClass已经分配了以下内容,则可以释放内存new:
auto& x = fun_ret_add(); // a
...
delete std::addressof(x); // b
Run Code Online (Sandbox Code Playgroud)
这需要:
第二个例子是类似的.在这种情况下,至少有一个提示需要删除该对象,但调用者仍然必须知道该对象已被分配new,并且他必须防止异常.
与此形成对比:
std::unique_ptr<myClass> fun_ret_ptr()
{
return std::make_unique<myClass>();
// or
return { new myClass() };
// or
return std::unique_ptr<myClass>(new myClass());
}
Run Code Online (Sandbox Code Playgroud)
现在调用者收到一个智能指针.如果主叫方不执行任何操作,但使用该指针,在myClass对象会得到妥善当指针超出范围中删除,并且所有内存将被回收.
| 归档时间: |
|
| 查看次数: |
261 次 |
| 最近记录: |