Tips for Boost shared_ptr

Source: Internet
Author: User

Class A <br/>{< br/> Public: <br/> virtual void print () = 0; <br/> protected: <br/> ~ A () <br/>{< br/> cout <"A destroyed... "<Endl; <br/>}< br/>}; <br/> Class B: public a <br/>{< br/> public: <br/> void print () <br/> {<br/> cout <"B: print... "<Endl; <br/>}< br/> ~ B () <br/>{< br/> cout <"B destroyed... "<Endl; <br/>}< br/>}; <br/> shared_ptr <A> createa () <br/>{< br/> shared_ptr <A> P (New B (); <br/> return P; <br/>}< br/> int main () <br/>{< br/> shared_ptr <A> A = createa (); <br/> A-> Print (); <br/> return 0; <br/>} 




This sectionCodeThere are two wonders:

1. The destructor of A is protected, and there is no error prompt during compilation.

2. A's destructor are not virtual, But B's destructor is called at last.


Shared_ptr is really eye-catching. Let's go to boost to find out what's going on.


Start with the Statement of shared_ptr:


Template <class T> class shared_ptr <br/>{< br/>... <br/> template <class Y> <br/> explicit shared_ptr (y * P): Px (P), Pn (P) // y must be complete <br/> {...} <br/>... 


Note that there are two variables, PX and Pn, to see how they are declared:


T * PX; // contained pointer <br/> boost: detail: shared_count PN; // Reference Counter 


Both PX and Pn use P for initialization. The PX type is the pointer of the module parameter t, but the PN type should be taken another look:


Class shared_count <br/>{< br/> template <class Y> explicit shared_count (y * P): PI _ (0) <br/>{< br/> PI _ = new sp_counted_impl_p <Y> (p); <br/>... 


The pi is defined:


Sp_counted_base * PI _;


We can see from the sp_counted_base class that this is the specific implementation of the reference count, which has no significance for our problem here, but the actual object sp_counted_impl_p pointed by Pi has some meanings:


Template <Class X> class sp_counted_impl_p: Public sp_counted_base <br/>{< br/> explicit sp_counted_impl_p (x * px): Px _ (PX) <br/> {} 


The PX _ statement is as follows:


X * PX _;



Okay, let's take a look at the above connection. The problem is clear.


When creating a shared_ptr <x> object, two pointers are actually initialized internally. One is Px in shared_ptr, and the value is P, and the other is pn, in shared_count, we can see that the actual type of P is the actual type of P. That is to say, the actual type of P can be different from the template parameter Type X of shared_ptr. Of course, it can only be a derivative relationship, otherwise, compilation fails.


In the initial example, the PX type is A, and the PN internal type is B.


In fact, the shared_ptr constructor has such a comment: "y must be complete", that is to say, the type of the original pointer must be complete, because then the compiler can check the True Type of the pointer, record this type in PN, and then call the correct destructor when releasing it.


However, if the pointer type is lost here, the result is naturally incorrect. For example, we can try it like this:


Shared_ptr <A> anothercreatea () <br/>{< br/> A * A = new B (); <br/> shared_ptr <A> P (); <br/> return P; <br/>} 


Of course, the compiler will prompt you That the destructor of A is protected and the object cannot be deleted. Yes, this is the problem. The parameter type passed to shared_ptr is A, and the pointer type recorded in PN is, therefore, when deleting the pointer object, he will only call the destructor of A. At this time, the compilation check is not passed.



Then let's take a look at why boost is doing this. A pointer is saved in two copies. Of course there is a reason for this. A closer look will show that the operation on the pointer uses the PX object saved in shared_ptr, while the pointer saved in PN is used when the pointer is deleted. In this way, we can understand that using the template parameter type pointer, which is generally the base class pointer to call the method, can well support polymorphism and use the original type pointer for deletion, in this way, objects can be safely deleted.


Boost is amazing.

 

Related Article

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.