关于shared_ptr使用的问题 - C++

发布于 2024-08-18 22:31:47 字数 1587 浏览 7 评论 0 原文

我对使用 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 吗?如果是,它有什么优势?当 T 没有无参数构造函数时,我们如何使用 make_shared 呢?

问题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

如何返回并检查 shared_ptr 对象上的 NULL?是不是类似“

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

任何帮助都会很棒”之类的内容。

I have few questions on the best practices of using shared_ptr.

Question 1

Is copying shared_ptr cheap? 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

Should I use boost::make_shared to construct a shared_ptr? If yes, what advantages it offers? And how can we use make_shared when T doesn't have a parameter-less constructor?

Question 3

How to use 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

How can I return and check for NULL on a shared_ptr object? 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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

再浓的妆也掩不了殇 2024-08-25 22:31:47

大多数问题已经得到解答,但我不同意共享指针副本很便宜。

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

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

Most of the questions have been answered, but I disagree that a shared_ptr copy is cheap.

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.

蒲公英的约定 2024-08-25 22:31:47
  1. 复制很便宜,指针不占用太多空间。它的重点是使其变小,以便允许按值在容器中使用(例如 std::vector> )。

  2. make_shared 采用可变数量的参数,并且是优于您自己构建的机制(就像 make_pair)。优点是可读性,特别是在涉及传递临时变量和/或命名空间的情况下:

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

  4. 智能指针具有重载运算符,可以直接在计算为 bool 的表达式中使用。不要使用get。对于任何事情。不要将 p.get 与任何内容进行比较,而是比较一个空指针实例 ( my_ptr != boost::shared_ptr() )

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 ));
  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 ( e.g. 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). The advantage is readability, especially if passing temporaries and/or namespaces is involved:

  3. boost::const_ptr_cast as already suggested

  4. smart pointers have overloaded operators and may be directly used in expressions evaluated to bool. Don't use get. For anything. Instead of comparing p.get to anything, compare a empty pointer instance ( my_ptr != boost::shared_ptr< MyClass >() )

AD.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 ));
自由如风 2024-08-25 22:31:47
  1. 是的,副本绝对便宜。除了保存指针之外,shared_ptr 类(通常)还有另一个数据成员 - 使用计数。
  2. 无法回答这个问题,我通常在引入 make_shared 之前使用 boost 版本(1.40?)
  3. 使用 boost::const_pointer_cast
  4. shared_ptr 已定义了operator==/!=。在上面的示例中: if (f)
  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.
  2. Can't answer this, I generally use boost versions before make_shared was introduced (1.40?)
  3. Use boost::const_pointer_cast
  4. shared_ptr has operator==/!= defined. In your example above: if (f)
剑心龙吟 2024-08-25 22:31:47
  1. 复制一个shared_ptr现在需要花费32个字节的堆栈复制和额外的引用计数增量/减量。决定它对你来说是否便宜,但我认为没有理由不传递 const 引用,特别是你已经有了 ptr 的 typedef:
    void f(const foo_ptr &myfoo)
    特别是考虑到 C++ 中传递的标准无写权限参数是 const 引用。复制

  2. 我希望没有任何函数接受不共享的指针。这与 Java 和 C# 中的参数传递语义类似(尽管不相同)。为什么每次都要深入决定如何传递对象,而不是采用一种标准方法来执行此操作?

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

  1. Copying a shared_ptr now costs 32 bytes in stack copy and extra refcount increments/decrements. 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.

  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#. 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. The boolean conversion semantics is pretty neat.

素染倾城色 2024-08-25 22:31:47
  1. Shared_ptr 存在的基本原因之一是复制成本相对较低。
  2. 有一些版本的 make_shared 接受参数(如果您的编译器支持可变参数模板,则该版本接受可变参数列表)。
  3. 听起来您正在寻找 const_ptr_cast ?
  4. 要返回空指针,可以将“0”传递给 share_ptr 构造函数。要检查空指针,可以将 p.get() 与 0 进行比较。
  1. One of the basic reasons for the existence of shared_ptr is to be relatively cheap to copy.
  2. There are versions of make_shared that take parameters (and if your compiler supports variadic templates, one that takes a variable parameter list).
  3. It sounds like you're looking for const_ptr_cast?
  4. To return a null pointer, you can pass '0' to the share_ptr ctor. To check for a null pointer, you can compare p.get() to 0.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文