使用unique_ptr作为方法参数 - 优点和缺点

时间:2015-05-10 00:25:18

标签: c++ unique-ptr

我注意到如果我有以下内容:

#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对象..当我movewobble实例的所有权时,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;
}

仍然在范围内保留对该变量的引用。

问:

  1. 我上面说的是正确的吗?
  2. 我想知道除了我指出的那些之外,使用unique_ptr和不使用unique_ptr是否有任何好处?

1 个答案:

答案 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引用会更加惯用。