我注意到如果我有以下内容:
#include <memory>
using namespace std;
class Foo
{
public:
Foo();
};
class Wobble
{
public:
void SetWibble( unique_ptr<Foo> foo )
{
this->wibble = move( foo );
}
// I like returning a ref as it gives control to
// the user of my framework over recieving a & or a copy
Foo& GetWibble()
{
return *wibble;
}
unique_ptr<Foo> wibble;
};
int _tmain(int argc, _TCHAR* argv[])
{
unique_ptr<Wobble> wobble;
unique_ptr<Foo> foo( new Foo() ); // Look here
foo->something = ...;
foo->something1 = ...;
foo->something2 = ...;
wobble->SetWibble( move( foo ) );
return 0;
}
...当我声明foo
时,我有一个很好的Foo
对象..当我move
对wobble
实例的所有权时,foo现在为空在int _tmain
范围内。
我非常喜欢这个,因为我认为它正在删除内存并清除int _tmain
范围内的指针...在我当前的上下文中不应该再被摆弄......而不是这个:
// ...
void SetWibble( Foo& foo )
{
this->wibble = foo;
}
// ...
int _tmain(int argc, _TCHAR* argv[])
{
unique_ptr<Wobble> wobble;
Foo foo;
foo.something = ...;
foo.something1 = ...;
foo.something2 = ...;
wobble->SetWibble( foo );
return 0;
}
仍然在范围内保留对该变量的引用。
问:
答案 0 :(得分:0)
两个示例之间的主要区别不是使用std::unique_ptr
,而是使用动态内存分配与堆栈上的分配。
通常最好在堆栈上分配对象。您将避免动态内存分配的成本和指针的不必要的间接(我看不出有任何理由不在堆栈上为{1}分配开始)。
如果您只关心在您的范围内使用变量,那么您可以将Wobble
的创建提取到单独的函数中:
Foo
或者,如果Foo createFoo() {
Foo foo;
foo.something = ...;
foo.something1 = ...;
foo.something2 = ...;
return foo;
}
int main() {
Wobble wobble;
wobble.SetWibble(createFoo());
}
可移动,您可以直接移动它而不是移动Foo
:
std::unique_ptr<Foo>
如果这样做,您可能希望针对r值引用优化int main() {
Wobble wobble;
Foo foo;
foo.something = ...;
foo.something1 = ...;
foo.something2 = ...;
wobble.SetWibble(std::move(foo));
}
。即使移动SetWibble
没有特别的效率优势,至少文档中的变量不应再被打乱。
如果foo
不可移动并且复制起来很昂贵,那么可能会有动态分配内存的原因。并且,是的,如果您要动态分配内存,最好使用Foo
管理该内存。
<强>题外话:强>
std::unique_ptr
中取消引用wibble
。您有保证GetWibble
不为空吗?它可能永远不会被设置,或者它可以被显式设置为wibble
也许这是调用nullptr
的前提条件,但它是指针的额外间接如何增加复杂性的一个示例。 / LI>
GetWibble
采用const引用会更加惯用。