In the previous chapter, I just learned about the proxy class and also talked about what problems it solves and how it works. this chapter immediately encountered a problem, and the proxy class indeed achieved a good unified management of a class of objects, but in some cases. for example, an object is large. a large object has its own characteristics. It has many resources and copying it takes a lot of space and time. however, the proxy class performs a lot of copy on the original class. so the problem arises. of course, for some small classes, but they need to be well managed, the proxy class is still very useful...
Bytes -------------------------------------------------------------------------------------------------------------------------------
Handle class to solve the problem.
Handle class, not just to solve the problem of proxy, it is only a small part .. but imagine such a situation. For example, I have a class that encapsulates operations on the database. the other two classes need to be called (this is a common problem .), all you need to do is to give the address of the Database Class Object to the other two classes, so the function is implemented. However, when I need to release the database object after completing the data inventory operation, this is a problem. (Of course, not releasing is not allowed ),
It is easy to think of a solution. You can add a private member that records the number of times this object was referenced in the previous database class and provide the corresponding access interface ..
Bytes -------------------------------------------------------------------------------------------------------------------------------
My understanding of the handle,
In my opinion, the handle is a sub-name. In order to manage our pointer (memory), we only add a counter to the class, we can still call this process a handle (in fact, the pointer is still the pointer, There is nothing special ).
If we regard the handle mentioned above as a factory concept, we should summarize the narrow concept (truly encapsulate the pointer to memory management ,)
In the second half of my freshman year, when I was studying MFC and Win32, I first heard about the concept of handle. I was confused about the new concept. At that time, the senior student told me that, let's take it as a pointer (at that time, there was no memory management at all, and there was no awareness of software security. Therefore, there would be no problem if we understood it as a pointer ), thinking in C ++, C ++ primary, and some other books, as well as some other projects that occasionally encounter on the Internet, and now read this book, each experience has an improvement in understanding (of course, it will continue to improve in the future ).
Below are some classic packages:
Class handle {
Public:
Handle ();
Handle (const Aclass &);
Handle (const Aclass *);
Handlw & operator = (const handle &);
~ Handle ()
{
If (-- count = 0)
Delete P;
}
PRIVATE:
//...
Aclass * P;
};
Most object-oriented handles (classes) generally contain these attributes. Many closed differences exist in the position where counter count is placed,
Certificate -----------------------------------------------------------------------------------------------------------------------------------------------------
1> count is a static public member of the handle class.
The static member of a class is used to stand at the height of the class (instead of an instance), so it can be used as a counter ,,
2> count is a member variable of the original class. It is used to count the number of pointers pointing to an object of the original class ..
The difference between this method and method 1> may be difficult to see... for example, we can easily find the differences between them.
#: The first method counter is for this class, and the second method is for every object of this class.
The first method requires that this class be instantiated only once. Why .. if you instantiate a counter twice (multiple times), they will share a counter (which is obviously dangerous ),
Therefore, the premise of using this method is that my class can complete the task as long as an instance and add a static control switch in the original class. When there is an instance, turn off the switch to prevent the instance from being instantiated again.
The second method does not have the above problem: But the Destructor should be changed:
Handle ::~ Handle ()
{
Count = P. getcount (); // here, count is a private member of the class and is accessed through an access interface.
If (-- count = 0)
Delete P;
Else
P. setcount (count );
}
In this way, count only contains specific objects, and multiple instances in the program can coexist.
3> define an adjoint class. The class has only the original object (reference) and counter. The handle class is basically the same as the above, but there is no direct original pointer, instead, it is the companion class pointer of the original class,
This method also has a benefit (of course, there is no benefit, so there is no need to use it .), that is, only the members implementing their own functions in the original class, but no external members (count) are put in the companion class.
The implementation method is similar to 2>. Here we will not write an example ....
Certificate -----------------------------------------------------------------------------------------------------------------------------------------------------
In fact, there are many implementation methods... if you are interested, you can discuss them together. In the future, if you encounter a classic one, you will organize it again...