C + + Smart pointers to deeply parse _c language

Source: Internet
Author: User
Tags constructor garbage collection gety

1. Why do I need a smart pointer?
Simply put, smart pointers are designed to implement garbage collection mechanisms similar to those in Java. The Java garbage collection mechanism frees programmers from the complexity of memory management tasks, and Java will automatically help recycle after applying for a chunk of memory without having to focus on where and when to release the memory. But for efficiency and other reasons (perhaps C + + designers disdain this fool's programming), C + + itself does not have such a function, and its cumbersome and error-prone memory management has been criticized by the vast number of programmers.

Further, the smart pointer appears to meet the needs of pointer members in the management class. Classes that contain pointer members need to pay special attention to replication control and assignment operations, because only the addresses in the pointer are copied when the pointer is copied, not the object to which the pointer points. When an instance of a class is destructor, it can cause a hanging pointer problem.

There are generally two ways to manage pointer members in a class: a value-type class that provides value semantics to pointer members (value semantics) and a different new copy when the value object is copied. The typical application of this approach is the string class. Another way is the smart pointer, the object that the pointer to the implementation of this method points to is shared.

2. Overview of Intelligent Pointer implementation
A common implementation technique for smart pointers (smart pointer) is to use reference counting (reference count). A smart pointer class relates a counter to an object that the class points to, and a reference count tracks how many objects in the class share the same pointer.
Initializes the pointer each time a new object of the class is created and a reference count of 1; When an object is created as a copy of another object, the copy constructor copies the pointer and increases the corresponding reference count; When an object is assigned, the assignment operator decreases the reference count of the object referred to by the left operand (if the reference count is reduced to 0, Deletes the object) and increases the reference count of the object referred to by the right operand; when the destructor is called, the constructor reduces the reference count (if the reference count is reduced to 0, the underlying object is deleted).
There are two classic strategies for implementing smart pointers: one is to introduce auxiliary classes and the other is to use handle classes.

3. Implementation Mode 1: Introduction of auxiliary classes
This method defines a separate specific class (REFPTR) to encapsulate the pointer and the corresponding reference count.

Copy Code code as follows:

Class Point//Underlying object classes
{
Public
Point (int xval = 0, int yval = 0): X (xval), Y (yval) {}
int GetX () const {return x;}
int GetY () const {return y;}
void SetX (int xval) {x = Xval;}
void sety (int yval) {y = Yval;}

Private
int x,y;
};
Class Refptr//Auxiliary classes
{//This class member access is all private because you do not want the user to use the class directly
Friend class Smartptr; Defines a smart pointer class as a friend because the smart pointer class needs to manipulate the helper class directly
Refptr (Point *ptr):p (PTR), COUNT (1) {}
~refptr () {delete p;}
int count; Reference count
Point *p; Underlying object pointer
};
Class Smartptr//Smart pointer classes
{
Public
Smartptr (Point *ptr): RP (New Refptr (PTR)) {}//constructor
Smartptr (const smartptr &SP): RP (SP.RP) {++rp->count;} Copy Constructors
smartptr& operator= (const smartptr& RHS) {//Overloaded assignment operator
++rhs.rp->count; First, reference the right operand to count plus 1,
if (--rp->count = = 0)//and then subtract the reference count by 1, you can respond to a self assignment
Delete RP;
RP = RHS.RP;
return *this;
}
~smartptr () {//destructor
if (--rp->count = 0)///When the reference count is reduced to 0 o'clock, delete the Auxiliary class object pointer, thereby deleting the underlying object
Delete RP;
}
Private
Refptr *RP; Helper Class object pointers
};
int main ()
{
Point *p1 = new Point (10, 8);
SMARTPTR SP1 (p1);
Smartptr SP2 (SP1);
Point *p2 = new Point (5, 5);
Smartptr SP3 (p2);
SP3 = SP1;
return 0;
}

The memory structure used in this way is as follows:

4. Implementation Mode 2: Using Handle class
In order to avoid each class using the pointer in the above scheme to control the reference count themselves, you can encapsulate the pointer with a class. After encapsulation, this class object can appear anywhere the user class uses the pointer, behaving as a pointer. We can use it like a pointer, without worrying about the problems of ordinary member pointers, we call such classes a handle class. When encapsulating a handle class, you need to request a dynamically allocated reference count space, which is stored separately from the reference count. The implementation example is as follows:
Copy Code code as follows:

Class Point//Underlying object classes
{
Public
Point (int xval = 0, int yval = 0): X (xval), Y (yval) {}
int GetX () const {return x;}
int GetY () const {return y;}
void SetX (int xval) {x = Xval;}
void sety (int yval) {y = Yval;}
Public
Virtual point* Clone () const {//virtual function, to enable a handle class to assign a new copy of a known object without knowing the exact type of the object
Return to New Point (*this);
}

Private
int x,y;
};
Class D3point:public Point//derived class
{
Public
D3point (int xval, int yval, int zval):P oint (Xval, yval), Z (zval) {}
int GetZ () const {return z;}
void Setz (int zval) {z = zval;}
Public
d3point* Clone () const {//virtual function, to enable a handle class to assign a new copy of a known object without knowing the exact type of the object
return new D3point (*this);
}
Private
int z;
};
Class Smartptr
{
Public
Smartptr (Point *ptr = 0):p (PTR), COUNT (new int (1)) {}//constructor
Smartptr (Point &point):p (Point.clone ()), COUNT (new int (1)) {}//constructor
Smartptr (const smartptr &SP):p (SP.P), COUNT (Sp.count) {++*count;} Copy Constructors
smartptr& operator= (const smartptr &SP) {//Overloaded assignment operator
++*sp.count; First, reference the right operand to count plus 1,
Decr_use (); Then subtract the reference count by 1, and you can handle the self assignment
p = SP.P;
Count = Sp.count;
return *this;
}
~smartptr () {//destructor
Decr_use ();
}
Public://generally do not implement these two operators, because we do not want users to directly manipulate the underlying object pointer
Const point* operator-> () const {
if (p) return p;
else throw Logic_error ("unbound point");
}
Const point& operator* () const {
if (p) return *p;
else throw Logic_error ("unbound point");
}
Private
void Decr_use () {
if (--*count = 0)
{
Delete p;
Delete count;
}
}
Private
Point *p; Underlying object pointer
int *count; Pointer to reference count
};
int main ()
{
Point *p1 = new Point (10, 8);
SMARTPTR SP1 (p1);
Smartptr SP2 (SP1);
D3point *p2 = new D3point (5, 5, 0);
Smartptr SP3 (p2);
return 0;
}

The memory structure used in this way is as follows:
<>

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.