简体   繁体   English

有关shared_ptr用法的问题-C ++

[英]Questions on usages of shared_ptr - C++

I have few questions on the best practices of using shared_ptr . 关于使用shared_ptr的最佳实践,我有几个问题。

Question 1 问题1

Is copying shared_ptr cheap? 复制shared_ptr便宜吗? Or do I need to pass it as reference to my own helper functions and return as value? 还是我需要将其作为对自己的辅助函数的引用并作为值返回? Something like, 就像是,

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);
}

Question 2 问题2

Should I use boost::make_shared to construct a shared_ptr ? 我应该使用boost::make_shared构造一个shared_ptr吗? If yes, what advantages it offers? 如果是,它提供什么优势? And how can we use make_shared when T doesn't have a parameter-less constructor? T没有无参数构造函数时,如何使用make_shared

Question 3 问题3

How to use const foo* ? 如何使用const foo* I have found two approaches for doing this. 我发现有两种方法可以做到这一点。

void take_const_foo(const foo* pfoo)
{

}

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

OR 要么

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;
}

Question 4 问题4

How can I return and check for NULL on a shared_ptr object? 如何在shared_ptr对象上返回并检查NULL Is it something like, 是这样吗

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;
}

Any help would be great. 任何帮助都会很棒。

Most of the questions have been answered, but I disagree that a shared_ptr copy is cheap. 大多数问题已得到解答,但我不同意shared_ptr副本便宜。

A copy has different semantics from a pass-by-reference. 副本与通过引用的语义不同 It will modify the reference count, which will trigger an atomic increment in the best case and a lock in the worst case. 它将修改引用计数,在最佳情况下将触发原子增量,在最坏情况下将触发锁。 You must decide what semantics you need and then you will know whether to pass by reference or by value. 您必须确定所需的语义,然后才能知道是按引用传递还是按值传递。

From a performance point of view, it's usually a better idea to use a boost pointer container instead of a container of shared_ptr. 从性能的角度来看,通常最好使用boost指针容器而不是shared_ptr容器。

  1. Copying is cheap, the pointer doesn't take much space. 复制很便宜,指针不会占用太多空间。 The whole point of it was to make it small to allow usage in containers by value ( eg std::vector< shared_ptr<Foo> > ). 这样做的全部目的是使它变小以允许按值在容器中使用(例如std::vector< shared_ptr<Foo> > )。

  2. make_shared takes a variable amount of parameters, and is the prefered mechanicsm over constructing it yourself (just like make_pair ). make_shared接受可变数量的参数,并且是优先于自己构造参数的机制(就像make_pair一样)。 The advantage is readability, especially if passing temporaries and/or namespaces is involved: 优点是可读性,尤其是在涉及传递临时对象和/或名称空间的情况下:

  3. boost::const_ptr_cast as already suggested 已经建议的boost :: const_ptr_cast

  4. smart pointers have overloaded operators and may be directly used in expressions evaluated to bool. 智能指针具有重载的运算符,可以直接在计算为bool的表达式中使用。 Don't use get . 不要使用get For anything. 为了任何东西。 Instead of comparing p.get to anything, compare a empty pointer instance ( my_ptr != boost::shared_ptr< MyClass >() ) 而不是将p.get与任何东西进行比较,而是比较一个空的指针实例( my_ptr != boost::shared_ptr< MyClass >()

AD.2 广告2

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

versus

func_shared( boost::make_shared<my_tools::MyLongNamedClass>( param1, param2 ));
  1. Yes, the copy is absolutely cheap. 是的,副本绝对便宜。 Besides holding the pointer, there is (usually) one other data member for the shared_ptr class - the use count. 除了持有指针之外,shared_ptr类通常还有一个其他数据成员-使用计数。
  2. Can't answer this, I generally use boost versions before make_shared was introduced (1.40?) 无法回答这个问题,我通常在引入make_shared之前使用Boost版本(1.40?)
  3. Use boost::const_pointer_cast 使用boost :: const_pointer_cast
  4. shared_ptr has operator==/!= defined. shared_ptr定义了operator == / !! In your example above: if (f) 在上面的示例中:如果(f)
  1. Copying a shared_ptr now costs 32 bytes in stack copy and extra refcount increments/decrements. 现在,复制一个shared_ptr会花费32字节的堆栈副本,并且需要额外的引用计数增量/减量。 Decide whether it is cheap for you or not, but I see no reason why not to pass a const reference, especially that you already have a typedef for the ptr: void f(const foo_ptr &myfoo) especially given that the standard no-write-permissions parameter passing in C++ is const reference. 决定它对您而言是否便宜,但我认为没有理由不传递const引用,尤其是您已经拥有ptr的typedef: void f(const foo_ptr &myfoo)尤其是考虑到标准的no-write- C ++中传递的权限参数是const参考。

  2. I would prefer having no functions that accept pointer that is not shared. 我希望没有接受不共享指针的函数。 This is similar (though not identical) to parameter passing semantics in Java and C#. 这与Java和C#中的参数传递语义相似(尽管不完全相同)。 Why dive into deciding every time how to pass an object, instead of having one standard way of doing it? 为什么每次都要决定如何传递对象,而不是采用一种标准的方式来做呢?

  3. Use if(p) just as for regular pointers. 就像常规指针一样使用if(p) The boolean conversion semantics is pretty neat. 布尔转换语义非常简洁。

  1. One of the basic reasons for the existence of shared_ptr is to be relatively cheap to copy. 存在shared_ptr的基本原因之一是复制相对便宜。
  2. There are versions of make_shared that take parameters (and if your compiler supports variadic templates, one that takes a variable parameter list). 有些版本的make_shared带有参数(如果编译器支持可变参数模板,则带有可变参数列表)。
  3. It sounds like you're looking for const_ptr_cast? 听起来您在寻找const_ptr_cast?
  4. To return a null pointer, you can pass '0' to the share_ptr ctor. 要返回空指针,可以将“ 0”传递给share_ptr ctor。 To check for a null pointer, you can compare p.get() to 0. 要检查空指针,可以将p.get()与0进行比较。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM