我有简单的类方法,如
Task TaskSample::Create(void)
{
Task task;
return task;
}
并收到临时警告。这段代码有问题吗? 我更喜欢不在这里使用指针
答案 0 :(得分:18)
如果这实际上是您的代码,则编译器可能出错。
然而,你更有可能写了这个:
Task& TaskSample::Create(void)
{
Task task;
return task;
}
删除&按值返回,而不是按引用返回。通过引用返回没有任何意义,因为当函数返回时task
将被销毁。
答案 1 :(得分:8)
以下两个代码段都在MS C ++中产生此错误:
警告C4172:返回地址 局部变量或临时
Task* Create(void)
{
Task task;
return &task;
}
Task& Create2(void)
{
Task task;
return task;
}
MSDN documentation非常简洁地描述了警告:
局部变量和临时对象 函数返回时被销毁, 所以返回的地址无效。
为了返回指向对象的指针,需要调用operator new
,因为在堆上分配的对象不会超出范围:
Task* Create(void)
{
Task* task = new Task();
return task;
}
完成任务后,不要忘记delete
该任务:
Task* task = Create();
delete task;
或者,您可以使用smart pointer:
void Test () {
boost::scoped_ptr<Task> spTask = Create();
spTask->Schedule();
} //<--- spTask is deleted here
我会依赖RVO并实际使用您发布的代码,而代码很可能不会给您发出警告。
void Test() {
Task task = Create();
}
Task Create(void)
{
Task task;
task.start = 10;
return task;
}
这可能会产生与此相当的东西,所以实际上,没有复制构造函数开销。
void Test() {
Task task;
Create(&task);
}
Task* Create(Task* __compilerGeneratedParam)
{
__compilerGeneratedParam->start = 10;
return __compilerGeneratedParam;
}
答案 2 :(得分:1)
现代编译器可以优化返回值以避免复制开销。通常按价值返回并不会损害绩效。
但是如果你需要通过引用返回,请使用shared_ptr。
shared_ptr<Task> TaskSample::Create(void)
{
shared_ptr<Task> ptr(new Task(...));
return ptr;
}
答案 3 :(得分:-3)
最好的是,通过引用传递对象如下
void TaskSample::Create(Task& data)
{
....
}