标签: unique-ptr

如何传递std :: unique_ptr?

我第一次尝试使用C++ 11 unique_ptr; 我正在替换我的一个项目中的多态原始指针,该指针由一个类拥有,但经常传递.

我以前的功能如下:

bool func(BaseClass* ptr, int other_arg) {
  bool val;
  // plain ordinary function that does something...
  return val;
}
Run Code Online (Sandbox Code Playgroud)

但我很快意识到我无法切换到:

bool func(std::unique_ptr<BaseClass> ptr, int other_arg);
Run Code Online (Sandbox Code Playgroud)

因为调用者必须处理函数的指针所有权,所以我不想这样做.那么,什么是我的问题的最佳解决方案?

我虽然将指针作为参考传递,如下所示:

bool func(const std::unique_ptr<BaseClass>& ptr, int other_arg);
Run Code Online (Sandbox Code Playgroud)

但是我觉得这样做非常不舒服,首先是因为传递已经输入的内容似乎并非本能,_ptr作为参考的参考.其次,因为功能签名变得更大.第三,因为在生成的代码中,需要两个连续的指针间接来达到我的变量.

c++ unique-ptr c++11

72
推荐指数
3
解决办法
5万
查看次数

unique_ptr是否保证在移动后存储nullptr?

unique_ptr保证存储nullptr移动之后?

std::unique_ptr<int> p1{new int{23}};
std::unique_ptr<int> p2{std::move(p1)};
assert(!p1); // is this always true?
Run Code Online (Sandbox Code Playgroud)

c++ unique-ptr move-semantics c++11

72
推荐指数
2
解决办法
7127
查看次数

为什么unique_ptr在shared_ptr只占用一个时会占用两个模板参数?

双方unique_ptrshared_ptr接受定制的析构函数他们所拥有的对象上调用.但在的情况下unique_ptr,析构函数作为一个模板参数传递,而类型shared_ptr的自定义析构函数将被指定为一个模板参数的构造函数.

template <class T, class D = default_delete<T>> 
class unique_ptr
{
    unique_ptr(T*, D&); //simplified
    ...
};
Run Code Online (Sandbox Code Playgroud)

template<class T>
class shared_ptr
{
    template<typename D>
    shared_ptr(T*, D); //simplified
    ...
};
Run Code Online (Sandbox Code Playgroud)

我不明白为什么会有这样的差异.需要什么?

c++ std shared-ptr unique-ptr c++11

63
推荐指数
1
解决办法
3714
查看次数

如何将std :: unique_ptr传递给函数

我怎样才能将std::unique_ptr函数传递给函数?可以说我有以下课程:

class A
{
public:
    A(int val)
    {
        _val = val;
    }

    int GetVal() { return _val; }
private:
    int _val;
};
Run Code Online (Sandbox Code Playgroud)

以下内容无法编译:

void MyFunc(unique_ptr<A> arg)
{
    cout << arg->GetVal() << endl;
}

int main(int argc, char* argv[])
{
    unique_ptr<A> ptr = unique_ptr<A>(new A(1234));
    MyFunc(ptr);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

为什么我不能传入std::unique_ptr函数?当然这是构造的主要目的吗?或者C++委员会是否打算让我回到原始的C风格指针并将其传递给它:

MyFunc(&(*ptr)); 
Run Code Online (Sandbox Code Playgroud)

最奇怪的是,为什么这是一种传递它的好方法?看起来非常不一致:

MyFunc(unique_ptr<A>(new A(1234)));
Run Code Online (Sandbox Code Playgroud)

c++ unique-ptr c++11

63
推荐指数
5
解决办法
6万
查看次数

使用unique_ptr进行前向声明?

我发现std::unique_ptr在下面的代码中结合使用前向声明类很有用.它编译并与GCC一起工作,但整个事情似乎有点奇怪,我想知道这是否是标准行为(即标准要求)?因为B声明时B不是完整的类型unique_ptr.

A.hpp

#include <memory>

class B;

class A {
    std::unique_ptr<B> myptr;
    // B::~B() can't be seen from here
public:
    ~A();
};
Run Code Online (Sandbox Code Playgroud)

A.cpp

#include "B.hpp"
//B.hpp has to be included, otherwise it doesn't work.

A::~A() = default; // without this line, it won't compile 
// however, any destructor definiton will do.
Run Code Online (Sandbox Code Playgroud)

我怀疑这与析构函数有关(因此需要调用析构函数unique_ptr<B>)是在特定的编译单元(A.cpp)中定义的.

c++ destructor forward-declaration unique-ptr

62
推荐指数
1
解决办法
3万
查看次数

我应该分配还是重置unique_ptr?

鉴于自有对象的生命周期与其所有者链接的常见情况,我可以使用两种方式之一的唯一指针..

它可以分配:

class owner
{
    std::unique_ptr<someObject> owned;    
public:
    owner()
    {
        owned=std::unique_ptr<someObject>(new someObject());        
    }
};
Run Code Online (Sandbox Code Playgroud)

可以使用重置方法:

class owner
{
    std::unique_ptr<someObject> owned;    
public:
    owner()
    {
        owned.reset(new someObject());
    }
};
Run Code Online (Sandbox Code Playgroud)

为了最佳实践,我应该更喜欢一种形式吗?

编辑:对不起伙计们.我简化了这个.堆分配发生在初始化方法中,而不是在ctor中.因此,我无法使用初始化列表.

c++ smart-pointers unique-ptr c++11

62
推荐指数
2
解决办法
4万
查看次数

我如何使用unique_ptr用于pimpl?

这是我在尝试将unique_ptr用于pimpl时所看到的简化.我选择了unique_ptr,因为我真的希望类拥有指针 - 我希望pimpl指针和类的生命周期相同.

无论如何,这是标题:

#ifndef HELP
#define HELP 1

#include <memory>

class Help
{

public:

  Help(int ii);
  ~Help() = default;

private:

  class Impl;
  std::unique_ptr<Impl> _M_impl;
};

#endif // HELP
Run Code Online (Sandbox Code Playgroud)

这是来源:

#include "Help.h"

class Help::Impl
{
public:
  Impl(int ii)
  : _M_i{ii}
  { }

private:

  int _M_i;
};

Help::Help(int ii)
: _M_impl{new Help::Impl{ii}}
{ }
Run Code Online (Sandbox Code Playgroud)

我可以将它们编译成一个库就好了.但是当我尝试在测试程序中使用它时,我得到了

ed@bad-horse:~/ext_distribution$ ../bin/bin/g++ -std=c++0x -o test_help test_help.cpp Help.cpp
In file included from /home/ed/bin/lib/gcc/x86_64-unknown-linux-gnu/4.7.0/../../../../include/c++/4.7.0/memory:86:0,
                 from Help.h:4,
                 from test_help.cpp:3:
/home/ed/bin/lib/gcc/x86_64-unknown-linux-gnu/4.7.0/../../../../include/c++/4.7.0/bits/unique_ptr.h: In instantiation of 'void std::default_delete<_Tp>::operator()(_Tp*) const [with _Tp = …
Run Code Online (Sandbox Code Playgroud)

c++ pimpl-idiom unique-ptr c++11

60
推荐指数
2
解决办法
2万
查看次数

unique_ptr到派生类,作为将unique_ptr带到基类的函数的参数

我试图unique_ptr在一个unique_ptr带有基类的函数中使用一个派生类.就像是:

class Base {};

class Derived : public Base {};

void f(unique_ptr<Base> const &base) {}

…

unique_ptr<Derived> derived = unique_ptr<Derived>(new Derived);
f(derived);
Run Code Online (Sandbox Code Playgroud)

如果我正确理解了这个答案,那么这段代码应该可行,但它会导致以下编译错误:

错误C2664:'f':无法将参数1从'std :: unique_ptr <_Ty>'转换为'const std :: unique_ptr <_Ty>&'

IntelliSense:没有合适的用户定义转换,从"std :: unique_ptr <Derived,std :: default_delete <Derived >>"到"const std :: unique_ptr <Base,std :: default_delete <Base >>"存在

如果我改变f采取unique_ptr<Derived> const &derived,它工作正常,但这不是我想要的.

难道我做错了什么?我该怎么做才能解决这个问题?

我正在使用Visual Studio 2012.

c++ unique-ptr c++11 visual-studio-2012

57
推荐指数
3
解决办法
5万
查看次数

"向下转换"unique_ptr <Base>到unique_ptr <Derived>

我有一系列工厂回归unique_ptr<Base>.引擎盖下,虽然,他们所提供的指针各种衍生类型,即unique_ptr<Derived>,unique_ptr<DerivedA>,unique_ptr<DerivedB>

鉴于DerivedA : Derived并且Derived : Base我们有:

unique_ptr<Base> DerivedAFactory() {
    return unique_ptr<Base>(new DerivedA);
}
Run Code Online (Sandbox Code Playgroud)

我需要做的是将指针从返回"转换" unique_ptr<Base>到某个派生级别(不一定是原始的内部级别).用伪代码说明:

unique_ptr<Derived> ptr = static_cast<unique_ptr<Derived>>(DerivedAFactory());
Run Code Online (Sandbox Code Playgroud)

我正在考虑通过从中释放对象unique_ptr,然后使用一个转换原始指针的函数并将其重新分配给另一个unique_ptr所需的风格(release在调用之前由调用者显式完成)来实现这一点:

unique_ptr<Derived> CastToDerived(Base* obj) {
    return unique_ptr<Derived>(static_cast<Derived*>(obj));
}
Run Code Online (Sandbox Code Playgroud)

这是有效的,还是/会有什么时髦吗?


PS.还有一个复杂的问题是,有些工厂驻留在运行时动态加载的DLL中,这意味着我需要确保生成的对象在创建它们的同一个上下文(堆空间)中被销毁.所有权的转移(通常发生在另一个上下文中)必须从原始上下文中提供删除.但除了必须与指针一起提供/转换删除器之外,铸造问题应该是相同的.

c++ smart-pointers factory-pattern unique-ptr c++11

56
推荐指数
1
解决办法
2万
查看次数

unique_ptr提升等价?

在boost库中是否有一些与C++ 1x的std :: unique_ptr等效的类?我正在寻找的行为是能够拥有异常安全的工厂功能,就像这样......

std::unique_ptr<Base> create_base()
{
    return std::unique_ptr<Base>(new Derived);
}

void some_other_function()
{
    std::unique_ptr<Base> b = create_base();

    // Do some stuff with b that may or may not throw an exception...

    // Now b is destructed automagically.
}
Run Code Online (Sandbox Code Playgroud)

编辑:现在,我正在使用这个黑客,这似乎是我能在这一点上得到的最好的......

Base* create_base()
{
    return new Derived;
}

void some_other_function()
{
    boost::scoped_ptr<Base> b = create_base();

    // Do some stuff with b that may or may not throw an exception...

    // Now b is deleted automagically.
}
Run Code Online (Sandbox Code Playgroud)

c++ boost unique-ptr c++11

55
推荐指数
4
解决办法
4万
查看次数