Realization of intelligent pointer in C + + __c++

Source: Internet
Author: User

C + + learning problems encountered in the record. Use of the textbook: "C + + Primer."

Smart pointers. What How.
What ' s The Smartpointer and how to impletment it?

What is a smart pointer.
By reference counting, automatically manages the lifetime of dynamically allocated memory, avoiding memory leaks or methods of dangling pointers.
Application Scenario:
If a member of a class is a pointer to a dynamically allocated block of memory, there are two ways to do this when replicating control:
1, the copy pointer to the block of memory, in order to avoid memory leaks, the class in the destructor release memory. This creates a waste of memory space, and the copy operation can also incur unnecessary overhead.
2, only copy the pointer. But a new problem has been introduced: when the memory block is freed by a pointer member of a replica object, the other pointers become so-called dangling pointers.

Smart pointers are introduced here to solve the problems in 2.


How to implement smart pointers.
To solve this problem, in Method 2, we add a reference counting method to manage the memory release of this object.
Suppose what we need to manage here is an int pointer IP pointing to the memory. The following figure:


The u_ptr is used to bind the pointer to a reference count, and the class Hasptr indirectly accesses the IP-pointing memory through a pointer member pointing to the u_ptr.
(Here should be limited, a memory block corresponds to only one U_ptr object)
The U_ptr reference count is initialized to 1.
All copy control operations on objects that are hasptr to the class modify the U_ptr reference count.
Each copy of this Hasptr object does not copy pointer IP to point to the memory block, but to U_ptr's use plus one.
In each object's destructor, it is judged whether use minus one is 0, and if so, destroys the memory block that the U_ptr object binds to.

//c++ Primer plus ... chapter 8 page253 #include <iostream> #include <string> #include

<new> using namespace std;
	Class u_ptr{Private:friend class Hasptr;
	int *ip;
	size_t use; u_ptr (int *p): IP (P), use (1) {} 
	~u_ptr () {cout << "u_ptr destructor...free mem ip =" << IP << endl; 
	Delete IP;

}
}; Class hasptr{Public:hasptr (const string &str, int *p): Name (str), PTR (new U_ptr (p)) {cout << name <<
	\thasptr do normal construct "<< Endl;  } hasptr (const string &str, const hasptr &orig): Name (str), PTR (orig.ptr) {cout << name << "\thasptr"
		Do copy construct "<< Endl; 
	++ptr->use;

	}//some friend operators friend std::ostream& operator<< (std::ostream&, const HASPTR &); hasptr& operator= (const hasptr &orig) {cout << name << "\thasptr do assignment from" << orig
		. name << Endl;
			if (orig.ptr = = this->ptr) {cout << "They are the same one, do nothing" << Endl;
		return *this; 
		} ++orig.ptr->use;
			if (--ptr->use = = 0) {cout << name << "\tdelete ptr" << Endl;
		Delete ptr; }else {cout << name <<
		"\tptr usecnt =" << ptr->use << Endl;
		ptr = orig.ptr;
	return *this;
		} ~hasptr () {--ptr->use;
		cout << name << "\thasptr destructor ... ptr usecnt =" << ptr->use << Endl; if (Ptr->use = = 0) {delete ptr;//here call u_ptr ' s destructor}}//some API int * GET_PTR () const {return P
	Tr->ip;}

	int Get_ptr_val () const {return * (PTR-&GT;IP);}
	void set_ptr (int *p) {ptr->ip = P;}

void Set_ptr_val (int i) {*ptr->ip = i;}
	Private:string name;
U_ptr *ptr;

}; std::ostream& operator<< (std::ostream& os, const hasptr &hp) {os << hp.name << "\tval =" &
	lt;< hp.get_ptr_val () << "\taddr =" << hp.get_ptr ();
return OS;
}//overloaded the operator "<<".
	int main (int argc, char const *argv[]) {int *a = new int (123);
	cout << Endl << "Normal constructor" << Endl;
	Hasptr CP1 ("CP1", a);

	cout << CP1 << Endl; cout << ENDL << "copy constructor" << Endl;
	Hasptr cp2 ("Cp2", CP1);
	Cp2.set_ptr_val (199);
	
	cout << cp2 << Endl;
	cout << Endl << "assignment operator" << Endl;
	CP2 = CP1;
	
	cout << cp2 << Endl;
	cout << Endl << "More hasptr to a" << Endl;
	Hasptr CP3 ("CP3", a);
	Hasptr CP4 ("CP4", a);
	cout << CP3 << Endl;

	cout << CP4 << Endl;
	if (a!=null) cout << "A is still keep the mem, addr =" << *a << Endl;

	else cout << "A has been free mem" << Endl;
	cout << Endl << "...". Exit from main "<< Endl;;". Delete (a);
Don't need free mem-return 0;
 }


Under Linux, compile with g++ and run the results:

Normal constructor
CP1	hasptr do normal construct
cp1	val = 123 addr	= 0x9f0d008

Copy Constructor
cp2	hasptr do copy construct
cp2	val = 199 addr	= 0x9f0d008

Assignment C12/>CP2	hasptr do assignment from CP1
They are the same, doing nothing
cp2	val = 199 addr	= 0x9f0d0

hasptr to a
cp3 hasptr does	normal construct CP4 hasptr
do	normal construct
CP3	val = 199	addr = 0x9f0d008
cp4	val = 199 addr	= 0x9f0d008
A is still keep the mem, addr = 1 It is ....

exit from main
CP4	hasptr destructor ... ptr usecnt = 0
u_ptr destructor...free (+). Mem IP = 0x9f0d008
cp3	hasptr destructor ... ptr usecnt = 0 u_ptr destructor...free
mem ip = 0x9f0d008
  
   CP2	hasptr destructor ... ptr usecnt = 1 cp1 hasptr
destructor	... ptr usecnt = 0
u_ptr destructor ... . free Mem IP = 0x9f0d008

  






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.