17

我对使用shared_ptr.

问题 1

抄袭shared_ptr便宜吗?还是我需要将它作为对我自己的辅助函数的引用并作为值返回?就像是,

void init_fields(boost::shared_ptr<foo>& /*p_foo*/);
void init_other_fields(boost::shared_ptr<foo>& /*p_foo*/);

boost::shared_ptr<foo> create_foo()
{
    boost::shared_ptr<foo> p_foo(new foo);
    init_fields(p_foo);
    init_other_fields(p_foo);
}

问题2

我应该boost::make_shared用来构造一个shared_ptr吗?如果是,它提供了哪些优势?make_sharedT没有无参数构造函数时,我们如何使用?

问题 3

如何使用const foo*?我找到了两种方法来做到这一点。

void take_const_foo(const foo* pfoo)
{

}

int main()
{
    boost::shared_ptr<foo> pfoo(new foo);
    take_const_foo(pfoo.get());
    return 0;
}

或者

typedef boost::shared_ptr<foo> p_foo;
typedef const boost::shared_ptr<const foo> const_p_foo;

void take_const_foo(const_p_foo pfoo)
{

}

int main()
{
     boost::shared_ptr<foo> pfoo(new foo);
     take_const_foo(pfoo);
     return 0;
}

问题 4

如何返回并检查NULL对象shared_ptr?是不是有点像,

boost::shared_ptr<foo> get_foo()
{
     boost::shared_ptr<foo> null_foo;
     return null_foo;
}

int main()
{
     boost::shared_ptr<foo> f = get_foo();
     if(f == NULL)
     {
          /* .. */
     }
     return 0;
}

任何帮助都会很棒。

4

5 回答 5

8

大多数问题都已得到解答,但我不同意 shared_ptr 副本很便宜。

副本与传递引用具有不同的语义。它将修改引用计数,这将在最好的情况下触发原子增量,在最坏的情况下触发锁定。你必须决定你需要什么语义,然后你就会知道是按引用传递还是按值传递。

从性能的角度来看,使用 boost 指针容器而不是 shared_ptr 容器通常是一个更好的主意。

于 2010-01-27T10:45:12.950 回答
4
  1. 复制很便宜,指针不会占用太多空间。它的全部意义在于使它变小以允许按值在容器中使用(例如std::vector< shared_ptr<Foo> >)。

  2. make_shared接受可变数量的参数,并且是自己构建它的首选机制(就像make_pair)。优点是可读性,尤其是在涉及传递临时和/或命名空间时:

  3. boost::const_ptr_cast正如已经建议的那样

  4. 智能指针具有重载的运算符,可以直接用于计算为 bool 的表达式中。不要使用get. 为了任何东西。与其比较p.get任何东西,不如比较一个空指针实例 ( my_ptr != boost::shared_ptr< MyClass >())

AD.2

func_shared( boost::shared_ptr<my_tools::MyLongNamedClass>( 
    new my_tools::MyLongNamedClass( param1, param2 ) );

相对

func_shared( boost::make_shared<my_tools::MyLongNamedClass>( param1, param2 ));
于 2010-01-27T09:13:48.953 回答
3
  1. 是的,副本绝对便宜。除了持有指针外,shared_ptr 类(通常)还有另一个数据成员——使用计数。
  2. 无法回答这个问题,我一般在引入 make_shared 之前使用 boost 版本(1.40?)
  3. 使用 boost::const_pointer_cast
  4. shared_ptr 定义了 operator==/!=。在上面的示例中: if (f)
于 2010-01-27T06:36:11.110 回答
3
  1. 复制 shared_ptr 现在需要 32 字节的堆栈复制和额外的引用计数增量/减量。决定它对你来说是否便宜,但我认为没有理由不传递一个 const 引用,特别是你已经有一个 ptr 的 typedef: void f(const foo_ptr &myfoo) 特别是考虑到在 C++ 中传递的标准 no-write-permissions 参数是 const参考。

  2. 我宁愿没有接受非共享指针的函数。这与 Java 和 C# 中的参数传递语义相似(尽管不相同)。为什么每次都潜心决定如何传递一个对象,而不是使用一种标准的方法呢?

  3. 与常规指针一样使用if(p)。布尔转换语义非常简洁。

于 2010-01-27T10:57:24.030 回答
2
  1. shared_ptr 存在的基本原因之一是复制起来相对便宜。
  2. 有接受参数的 make_shared 版本(如果您的编译器支持可变参数模板,则接受可变参数列表的版本)。
  3. 听起来您正在寻找 const_ptr_cast?
  4. 要返回空指针,您可以将“0”传递给 share_ptr ctor。要检查空指针,您可以将 p.get() 与 0 进行比较。
于 2010-01-27T06:02:16.397 回答