Strong pointer and weak pointer of OSG smart pointer

Source: Internet
Author: User
Tags one more line

people who use OSG know that OSG's memory management approach uses smart pointers that allow OSG to handle object destruction by means of smart pointers. There are two smart pointer types in OSG, one is the ref_ptr we are familiar with, and the other one may not always be used by many people, but it's really very good observer_ptr. Both of these types appear as smart pointers, so what's the difference between them? Why are there two things like that? Let's slowly uncover their veil.
In fact, they are two kinds of smart pointer types, one is familiar with the strong pointer type (strong pointer), one is a weak pointer type (weak pointer), REF_PTR is a strong pointer type, OBSERVER_PTR is a weak pointer type, The strong pointer type ref_ptr is the same as the smart pointer type of the general meaning, by reference counting to record how many objects are using the object, when no object is used by that object, and observer_ptr points to an object, but it does not have a reference count function. It only records the address of the object, and when the object is destroyed elsewhere, the object address obtained through OBSERVER_PTR will be empty. Why call it a weak pointer, I do not know how the concept of the author is how to think, personal feelings may be because it is only a record of the object address, do not participate in the lifetime management of the object, so called weak. I do not know if you think so, anyway, I think so, haha.
when it comes to the question, why do we need multiple mentally retarded pointers? Isn't that more than a moron? Is it enough for a ref_ptr? I say my opinion, do not know is not accurate, only represents the personal point of view, if we only use ref_ptr, that means that in any case as long as we need to refer to an object, it is necessary to increase its reference count, not to reduce the reference count, we have to clear the first problem is that if the number of objects is particularly large , frequently increasing the reference count and reducing the reference count itself will reduce certain new energy, which should not be questioned, in addition, in many cases we just need to reference the object to facilitate access during the object lifetime, and if you use REF_PTR to increase its reference count will change the lifetime of the object, The lifetime of an object requires ourselves to be controlled by additional means, which inevitably adds to the complexity of the system, such as the creation of a number of aircraft in the system, and an aircraft manager that manages all aircraft in a unified way, and the normal logic is that when the plane explodes, we destroy the aircraft object, If we use REF_PTR in the aircraft manager, the aircraft object will not be destroyed automatically after the aircraft has been completely dereferenced elsewhere, as there is a reference to it in the aircraft manager. A certain judgment must be used to dereference the aircraft object from the aircraft manager to reduce the aircraft object reference count to 0 and destroy the object. Have we done something that's not flattering? If we use observer_ptr, we will not be bothered by this because it does not interfere with the lifetime of the object, and it does not reduce efficiency because of the reference counting operation. This is a personal understanding of why the mentally retarded can be a pointer to the reasons, may not be accurate or not comprehensive, welcome to amend the supplement, right here when a point.
Let's take a look at how observer_ptr implements a reference to an object, and how to do that when the object is destroyed observer_ptr know the situation. It's really simple, by name we can guess that the observer pattern is used, and the observer is automatically notified when the object is destroyed. Let's look at the code below to see if this is the case.
first of all we must see is the smart pointer constructor, it has a number of constructors, we use the most common and most typical of the view, the other is similar.
observer_ptr (t* RP)
    {
_reference = rp? Rp->getorcreateobserverset (): 0;
_ptr = (_reference.valid () && _reference->getobserverdobject ()!=0)? rp:0;
    }
this is the same as ref_ptr through a primitive object to construct, in the constructor to do one thing, is the initialization of member variables, the member variable total of two, one is called the Observer collection of the object, and the other is the same as ref_ptr is the pointer of the original object referenced by the smart pointer. The focus here is on the member of the Observer collection, which is actually an observer of the object, which is notified when the object is destroyed elsewhere.
in fact the above RP, _ptr and_reference->getobserverdobject () is a thing, we think, if not the same is the end of it? Because what we have to quote and observe must be a thing! Any subclass that inherits from the referenced class can have a collection of observers, an observer set to observe an object, a collection that can have several observers, and no observers in the observer's collection, just the object being observed, so we don't say it to prevent interference, Interested can look at the code.Rp->getorcreateobserverset () is the creation of an observer collection for the object referenced by the smart pointer, which naturally tells the Observer collection to observe itself when creating the Observer collection, not believing? Code for Proof:
observerset* Referenced::getorcreateobserverset () const
{
......
observerset* newobserverset = new Observerset (this);
......
}
You should know what you just said.RP, _ptr, and_reference->getobserverdobject () Why is it a thing?
Well, we already know how observer_ptr is observing the object of its reference, and how did it know when it was destroyed? What the? You don't believe it knows? Whether you believe it or not, I believe it anyway. Look at the code:
void Referenced::signalobserversanddelete (bool signaldelete, BOOL doDelete) const
{
......
if (Observerset && signaldelete)
{
Observerset->signalobjectdeleted (const_cast<referenced*> (this));
}
......
}

void observerset::signalobjectdeleted (void* ptr)
{
......
_observedobject = 0;
}

See, when the object it refers to is destroyed, it tells the Observer to gather: the object you have observed is not:_observedobject = 0;
Here, I'll pick it up as soon as I get there. Come on, don't worry, let's look at one more line of code:
Inline t* get () const {return (_reference.valid () && _reference->getobserverdobject ()!=0)? _ptr:0;}
What did you see? What if the object is destroyed and what is it returned? Empty! You got it right, don't forget. It does not increase the reference count of the referenced object, and does not modify the lifetime of the referenced object, which means that the object you are referencing may have been destroyed elsewhere when you use it, so be sure not to make a decision when using it, or it's easy to "Bang!" "A sound.
Are you done? Oh, no, and a little bit, what if I use the object when the other thread is destroyed in the process? Oh, really, yes, what should I do? Do not have to use ref_ptr, yes, this time will be used ref_ptr, or you are on the roof of the tile, the next king of eight eggs to you moved the ladder you fell dead. With ref_ptr! But not to let you abandon observer_ptr don't just use ref_ptr oh, look at the code I'll tell you what to use:
BOOL Lock (ref_ptr<t>& rptr) const
{
if (!_reference)
{
Rptr = 0;
return false;
}


referenced* obj = _reference->addreflock ();
if (!obj)
{
Rptr = 0;
return false;
}


Rptr = _ptr;
Obj->unref_nodelete ();
return Rptr.valid ();
}
{
Rptr = 0;
return false;
}


referenced* obj = _reference->addreflock ();
if (!obj)
{
Rptr = 0;
return false;
}


Rptr = _ptr;
Obj->unref_nodelete ();
return Rptr.valid ();
}
This time, you know what to do if you realize there's a potential for this? I will not translate, see two official notes:
The comment for this function is:
/**
* Assign the Observer_ptr to a ref_ptr. The ref_ptr'll be valid if the
* Referenced object hasn ' t been deleted and has a ref count > 0.
*/

There are also comments on the observer_ptr:
* If You and doubt about whether it's safe to access the object safe then use the
* ref_ptr<> Observer_ptr<>.lock () combination. */
All finished!

Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

Strong pointer and weak pointer of OSG smart pointer

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.