什么是boost的shared_ptr(shared_ptr const & r, T * p) ?

[英]What is boost's shared_ptr(shared_ptr const & r, T * p) used for?


boost::shared_ptr has an unusual constructor

boost::shared_ptr有一个不同寻常的构造函数。

template<class Y> shared_ptr(shared_ptr<Y> const & r, T * p);

and I am a little puzzled as to what this would be useful for. Basically it shares ownership with r, but .get() will return p. not r.get()!

我有点不明白这对什么有用。基本上它与r共享所有权,但是.get()将返回p. not .get()!

This means you can do something like this:

这意味着你可以这样做:

int main() {
    boost::shared_ptr<int> x(new int);
    boost::shared_ptr<int> y(x, new int);

    std::cout << x.get() << std::endl;
    std::cout << y.get() << std::endl;

    std::cout << x.use_count() << std::endl;
    std::cout << y.use_count() << std::endl;
}

And you will get this:

你会得到这个:

0x8c66008
0x8c66030
2
2

Note that the pointers are separate, but they both claim to have a use_count of 2 (since they share ownership of the same object).

注意指针是分开的,但是它们都声称拥有use_count(2)(因为它们共享同一对象的所有权)。

So, the int owned by x will exist as long as x or y is around. And if I understand the docs correct, the second int never gets destructed. I've confirmed this with the following test program:

因此,只要x或y在周围,x就会存在。如果我理解了文档的正确性,第二个int就不会被破坏。我已经通过以下测试程序确认了这一点:

struct T {
    T() { std::cout << "T()" << std::endl; }
    ~T() { std::cout << "~T()" << std::endl; }
};

int main() {
    boost::shared_ptr<T> x(new T);
    boost::shared_ptr<T> y(x, new T);

    std::cout << x.get() << std::endl;
    std::cout << y.get() << std::endl;

    std::cout << x.use_count() << std::endl;
    std::cout << y.use_count() << std::endl;
}

This outputs (as expected):

这个输出(预计):

T()
T()
0x96c2008
0x96c2030
2
2
~T()

So... what is the usefulness of this unusual construct which shares ownership of one pointer, but acts like another pointer (which it does not own) when used.

所以…这种不寻常的结构的用处是什么,它共享一个指针的所有权,但是在使用时就像另一个指针(它没有自己的指针)。

6 个解决方案

#1


29  

It is useful when you want to share a class member and an instance of the class is already a shared_ptr, like the following:

当您想要共享一个类成员时,它是有用的,并且这个类的实例已经是shared_ptr,就像下面这样:

struct A
{
  int *B; // managed inside A
};

shared_ptr<A>   a( new A );
shared_ptr<int> b( a, a->B );

they share the use count and stuff. It is optimization for memory usage.

他们共享使用计数之类的东西。它是对内存使用的优化。

#2


8  

To expand on leiz's and piotr's answers, this description of shared_ptr<> 'aliasing' is from a WG21 paper, "Improving shared_ptr for C++0x, Revision 2":

为了扩展leiz和piotr的答案,对shared_ptr<> ' ali'的描述来自WG21的一篇文章,“改进shared_ptr为c++ 0x,修订2”:

III. Aliasing Support

三世。混叠的支持

Advanced users often require the ability to create a shared_ptr instance p that shares ownership with another (master) shared_ptr q but points to an object that is not a base of *q. *p may be a member or an element of *q, for example. This section proposes an additional constructor that can be used for this purpose.

高级用户通常需要创建shared_ptr实例p的能力,该实例p与另一个(master) shared_ptr q共享所有权,但指向的对象不是*q的基础。例如,p可以是*q的成员或元素。本节提出了一个可以用于此目的的额外构造函数。

An interesting side effect of this increase of expressive power is that now the *_pointer_cast functions can be implemented in user code. The make_shared factory function presented later in this document can also be implemented using only the public interface of shared_ptr via the aliasing constructor.

这种表达能力增加的一个有趣的副作用是,现在*_pointer_cast函数可以在用户代码中实现。稍后在本文档中展示的make_shared factory函数也可以通过使用shared_ptr的公共接口通过别名构造函数实现。

Impact:

影响:

This feature extends the interface of shared_ptr in a backward-compatible way that increases its expressive power and is therefore strongly recommended to be added to the C++0x standard. It introduces no source- and binary compatibility issues.

这个特性扩展了shared_ptr的接口,以一种向后兼容的方式增加了它的表达能力,因此强烈建议将其添加到c++ 0x标准中。它没有引入任何源和二进制兼容性问题。

Proposed text:

提出了文本:

Add to shared_ptr [util.smartptr.shared] the following constructor:

添加到要查看[util.smartptr。共享)构造函数如下:

template<class Y> shared_ptr( shared_ptr<Y> const & r, T * p );

Add the following to [util.smartptr.shared.const]:

将以下内容添加到[util. smartptr.shary.const]:

template<class Y> shared_ptr( shared_ptr<Y> const & r, T * p );

Effects: Constructs a shared_ptr instance that stores p and shares ownership with r.

效果:构建一个shared_ptr实例,该实例存储p并与r共享所有权。

Postconditions: get() == p && use_count() == r.use_count().

Postconditions: get() == p && use_count() == r.use_count()。

Throws: nothing.

抛出:没有。

[Note: To avoid the possibility of a dangling pointer, the user of this constructor must ensure that p remains valid at least until the ownership group of r is destroyed. --end note.]

[注意:为了避免悬浮指针的存在,这个构造函数的用户必须确保p仍然有效,直到r的所有权组被销毁为止。——注意结束。)

[Note: This constructor allows creation of an empty shared_ptr instance with a non-NULL stored pointer. --end note.]

[注意:这个构造函数允许创建一个空的shared_ptr实例和一个非空的存储指针。——注意结束。)

#3


4  

You can also use this to keep dynamic casted pointers, i.e.:

您还可以使用它来保存动态的casted指针,即:

class A {};
class B: public A {};

shared_ptr<A> a(new B);
shared_ptr<B> b(a, dynamic_cast<B*>(a.get()));

#4


2  

You might have a pointer to some driver or a lower level api's data structure that may allocate additional data by its lower level api or other means. In this case it might be interesting to increase the use_count but return the additional data if the first pointer owns the other data pointers.

您可能有一个指向某个驱动程序或较低级api的数据结构的指针,这些数据结构可以通过它的低级api或其他方法来分配额外的数据。在这种情况下,增加use_count可能很有趣,但是如果第一个指针拥有其他数据指针,则返回额外的数据。

#5


0  

I have put shared_ptr's aliasing constructor in use in my little library:

我已经将shared_ptr的别名构造函数应用到我的小库中:

http://code.google.com/p/infectorpp/ (just my simple IoC container)

http://code.google.com/p/infectorpp/(只是我简单的IoC容器)

The point is that since I needed a shared_ptr of known type to be returned from a polymorphic class (that does not know the type). I was not able to implicitly convert the shared_ptr to the type I needed.

重点是,因为我需要从一个多态类返回已知类型的shared_ptr(它不知道类型)。我不能隐式地将shared_ptr转换为我需要的类型。

In the file "InfectorHelpers.hpp" (line 72-99) you can see that in action for the type IAnyShared.

在文件“InfectorHelpers。hpp(第72-99行)您可以看到,对于类型IAnyShared的操作。

Aliasing constructor creates shared_ptr that does not delete the pointers they are actually pointing to, but they still increase the reference counter to the original object and that can be tremendously usefull.

别名构造函数创建shared_ptr,它不会删除它们实际指向的指针,但它们仍然会增加对原始对象的引用计数器,这将非常有用。

Basically you can create a pointer to anything using aliasing constructor and threat it as a reference counter.

基本上,您可以创建一个指向任何使用别名构造函数的指针,并将其作为引用计数器进行威胁。

//my class
std::shared_ptr<T> ist;
int a; //dummy variable. I need its adress

virtual std::shared_ptr<int> getReferenceCounter(){
    return std::shared_ptr<int>(ist,&a); //not intended for dereferencing
}

virtual void* getPtr(); //return raw pointer to T

now we have both "a reference counter" and a pointer to a istance of T, enough data to create something with the aliasing constructor

现在我们有了“一个引用计数器”和一个指向T的istance的指针,足够的数据来创建具有别名构造函数的东西。

std::shared_ptr<T> aPtr( any->getReferenceCounter(), //share same ref counter 
               static_cast<T*>(any->getPtr()) ); //potentially unsafe cast!

I don't pretend to have invented this use for the aliasing constructor, but I never seen someone else doing the same. If you are guessing if that dirty code works the answer is yes.

我并没有假装发明了这个用于混叠构造函数的方法,但是我从来没有看到其他人也这么做。如果你在猜测这个脏代码是否有效,答案是肯定的。

#6


0  

For "shared_ptr<B> b(a, dynamic_cast<B*>(a.get()));"

“要< B > B(a,dynamic_cast < B * >(a.get()));“

I think it is not the recommended way using smart pointer.

我认为这不是推荐使用智能指针的方法。

The recommended way of doing this type conversion should be:

这种类型转换的推荐方法应该是:

shared_ptr<B> b(a);

Since in Boost document it is mentioned that:

因为在Boost文档中,它被提到:

shared_ptr<T> can be implicitly converted to shared_ptr<U> whenever T* can be implicitly converted to U*. In particular, shared_ptr<T> is implicitly convertible to shared_ptr<T> const, to shared_ptr<U> where U is an accessible base of T, and to shared_ptr<void>.

shared_ptr 可以隐式转换为shared_ptr ,只要T*可以隐式转换为U*。具体来说,shared_ptr 可以隐式转换到shared_ptr const,到shared_ptr ,在这里U是T的可访问的基础,并且shared_ptr

In addition to that, we also have dynamic_pointer_cast which could directly do conversion on Smart Pointer object and both of these two methods would be much safer than the manually casting raw pointer way.

除此之外,我们还拥有dynamic_pointer_cast,它可以直接对智能指针对象进行转换,这两种方法都比手工浇注原始指针方式要安全得多。

智能推荐

注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:http://www.itdaan.com/blog/2009/09/10/f9d4c11bd85caf7b40d37778fab8f22c.html



 
© 2014-2019 ITdaan.com 粤ICP备14056181号  

赞助商广告