开发者

c++ taking address of temporary

开发者 https://www.devze.com 2023-01-08 19:05 出处:网络
I\'ve simple class method like Task TaskSample::Create(void) { Task task; return task; } and got warning taking address of temporary. Is something wrong with this code开发者_Python百科 ?

I've simple class method like

Task TaskSample::Create(void)
{
    Task task;
    return task;
}

and got warning taking address of temporary. Is something wrong with this code开发者_Python百科 ? I prefer to not use pointer here


If that is actually what your code is, then the compiler is probably in error.

More likely, however, you actually wrote this:

Task& TaskSample::Create(void)
{
    Task task;
    return task;
}

Remove the & to return by value, instead of by reference. Returning by reference there makes no sense because task will be destroyed when the function returns.


Both of the following code snippets produce this error in MS C++:

warning C4172: returning address of local variable or temporary

Task* Create(void)
{
    Task task;
    return &task;
}
Task& Create2(void)
{
    Task task;
    return task;
}

MSDN documentation describes the warning quite succintly:

Local variables and temporary objects are destroyed when a function returns, so the address returned is not valid.

In order to return a pointer to an object you need to call operator new as an object allocated on the heap will not go out of scope:

Task* Create(void)
{
    Task* task = new Task();
    return task;
}

Don't forget to delete that task once you are done with it:

Task* task = Create();
delete task;

Alternatively you can use a smart pointer:

void Test () {
  boost::scoped_ptr<Task> spTask = Create();
  spTask->Schedule(); 
} //<--- spTask is deleted here

I would instead rely on RVO and actually use the code that you posted and which is most likely not the code giving you a warning.

void Test() {
   Task task = Create();
}

Task Create(void)
{
    Task task;
    task.start = 10;
    return task;
}

This may generate something equivalent to this, so really, there is no copy constructor overhead.

void Test() {
   Task task;
   Create(&task);
}

Task* Create(Task* __compilerGeneratedParam)
{
    __compilerGeneratedParam->start = 10;
    return __compilerGeneratedParam;
}   


Modern compilers can optimize return value to avoid copying overhead. Often returning by value doesn't hurt performance at all.

But if you need to return by reference, use shared_ptr instead.

shared_ptr<Task> TaskSample::Create(void)
{
    shared_ptr<Task> ptr(new Task(...));
    return ptr;
}


The best would be, to pass the object by reference as follows

void TaskSample::Create(Task& data)
{

....

}
0

精彩评论

暂无评论...
验证码 换一张
取 消