0

在下面的四种方法中,只有更好的是我们应该做的。我们希望在这里动态分配以避免错误的函数返回。但是,我们在哪里删除 f?在调用 better() 的函数处删除?但是在那种情况下不再有 f 了。

Foo *bad() {
  Foo f;
  return &f;
}

Foo &alsoBad() {
  Foo f;
  return f;
}

Foo mediocre() {
  Foo f;
  return f;
}

Foo * better() {
  Foo *f = new Foo;
  return f;
}
4

1 回答 1

5

但是在那种情况下不再有 f 了。

好吧,指针f超出了范围,这是真的,但我们仍然返回指向指向的同一个对象的指针f

因此,我们仍然拥有该对象的句柄,并且我们仍然可以调用delete返回的指针。事实上,您可以delete 使用new.

你需要注意的是:

  • you do indeed invoke delete at some point for each object allocated with new (otherwise you have a memory leak);
  • you do not call delete more than once for the same object, otherwise you get undefined behavior;
  • you do not dereference a pointer which points to an object that has been destroyed (i.e. a "dangling pointer"), otherwise you get undefined behavior.

In general, manual memory management through new and delete is discouraged in Modern C++, and ownership policies should be realized through smart pointers instead. OR...

In the four method below, only better is what we should do

Not exactly. In fact, I would say we should definitely not do better() - although we could do a version of better() modified to create and return a smart pointer rather than an owning raw pointer.

However, function mediocre() is actually pretty good, and that is for two reasons:

  1. First of all because it is very likely that the compiler will elide the call to the copy constructor and perform (Named) Return Value optimization, thus resulting in no run-time overhead;
  2. Secondly, because thanks to C++11's move semantics, it is possible to equip Foo with a move constructor that makes returning by value efficient in most cases even when no elision is performed.

Moreover, as Zoidberg correctly mentions in the comments, you should not use pointers at all if you do not really need them. Unique ownership can often by realized by creating objects with automatic storage duration (aka "on the stack"), and move semantics makes this practice efficient. Pointers should be created only when you need reference semantics.

于 2013-03-30T00:47:35.483 回答