About "Deep Exploration C + + object Model" Pause for half a month, today continue to chew this bone, my study into the fourth chapter, functional semantics. Let's do a review. C + + supports three member functions: static, Virtual, and non-static. Each function of the invocation is different, of course, their role will also have a difference, in general, we only have to master according to our needs to use these three types of member functions correctly, as for the internal how to do we can not know. But the deep exploration of the C + + object model is just a book that allows us to explore the depths of what we don't know. Through the previous study, I think I know some things that I didn't know before, but the feeling did not improve how much, perhaps my study of this book still stay in a relatively superficial level. I think I should take the time to see it a few more times. It's a bit off track, because Thor wants to make it very easy to say that these notes are just some of the ideas that Thor reads, and if you look at it for reference only, it seems to me that I have only explored not very deep. Our most common design and use of classes is non-static member functions, which use member functions to encapsulate and hide our data, which I think is the most obvious difference between a member function and an external function. But are their efficiencies different? We do not want to use member functions in order to protect our data, which ultimately leads to inefficient results. Let's take a look at what the Non-static member function was like when it was actually executed.
Float Magnitude3d (const Point3D *_this) {...}
This is an external function, it has parameters. Indicates that it indirectly obtains the coordinate (Point3D) member.
float Point3d::mangnitude3d () const {...}
This is a member function that directly obtains the coordinates (POINT3D) of the members.
On the surface, it seems that member functions are much more efficient, but are they actually as efficient as we think? Not too. In fact, a member function is internally transformed into an external function.
1. A this pointer is added to the parameter of the member function to enable the object of the class to invoke the function.
2. Change the access to all non-static data members to be accessed by this.
3, the function of the name of a new process, so that it becomes unique in the program.
After that, after the transition, the member function has become a non member function.
float Point3d::mangnitude3d () const {...} The member function will be turned into the following
Pseudo code
MANGNITUDE3D__7POINT3DFV (Register Point3D * const this)
{
return sqrt (this->_x * this->x+
This->_y * this->y+
This->_z * this->z);
}
The operation that calls this function is also converted
obj. Mangnitude3d ()
be converted into:
MANGNITUDE3D__7POINT3DFV (*obj);
How do you see it, it's no different from the non-member function we started declaring. So it came to the conclusion that two iron balls landed at the same time.
In general, the name of a member is preceded by the name of the class, creating a unique name. In fact, when dealing with a member name, in addition to the class name, you will also add the list of parameters to ensure that the result is unique.
We're going to look at the static member function. We have the notion that the invocation of a member function must be an object of the class, like this obj.fun (), or such ptr->fun (). But in fact, only one or more static data members can be accessed by a member function to require the object of the class. class provides a pointer to this, which is used to bind non-static data members to the corresponding members of the class object. If no member data is used, there is no need to use the this pointer, and there is no need to invoke a member function through the object of the class. And we also know that static data members are outside the class and can be viewed as global variables, except that they are visible only within the life span of a class. (Refer to previous notes). And generally we will declare the static data member as a non-public. So we have to provide one or more member functions to access this member. Although we can access static data members without relying on the object of the class, the function that can be used to access static members does have to be bound to the object of the class. In order to solve this problem better, cfront2.0 introduces the concept of static member function.
A static member function is without this pointer. Because it does not need to be invoked through the object of the class. And it cannot directly access Non-static members in a class. And can not be declared as Virtual,const,volatile. If you get the address of a static member function, then we get the position of the function in memory. (The address of a non-static member function we get is a pointer to this class member function, a function pointer). You can see that because static member functions do not have this pointer, they are very similar to non-member functions.
With the basics of the previous chapters, it seems that these descriptions are not very difficult to understand, and our ideas can follow the book on the way down, this is the fun of reading, if a book to read all want to read the first chapter of such a strenuous, I think I can not read the possibility of a very high.
To continue our study, the following book begins the virtual function. We know that virtual function is a very important feature of C + +, and object-oriented polymorphism is realized by virtual function. The concept of polymorphism is a pointer (or reference) of a public base class that addresses a derived class object. The model of virtual function implementation is this. Each class has a virtual function table that contains the address of a function virtual function in the class, and when the class produces an object, it has a pointer to the virtual function table. In order to support the mechanism of virtual function, there is the form of "execution phase polymorphism".
Here's the thing.
We can define a pointer to a base class.
Point *ptr;
Then, during the execution period, he addresses the object we need. Can be
PTR =new point2d;
can also be
Ptr=new Pont3d;
The PTR pointer is responsible for allowing a program to take a set of types derived from a base class anywhere. This polymorphic form is negative because it must be completed at compile time. Corresponding to this is a positive form of polymorphism, that is, the completion of the implementation of a pointer or reference to find our object of a derived class.
Like the following:
Ptr->z ();
To achieve our purpose, this function z () should be a virtual function, and should also know the true type of the object that PTR refers to so that we can select the entity of Z (). And the position of the Z () entity so that we can call it. These work compilers will do a good job for us, how does the compiler do it?
We know that each class has a virtual function table that contains the addresses of all the virtual function entities of the object of the corresponding class, and may overwrite a virtual function entity of a base class. If you do not overwrite a virtual function entity that exists for the base class, the function entity of the base class is inherited, which is not finished, and there is a function entity for the pure_virtual_called (). Each virtual function, whether inherited or rewritten, is assigned a fixed index value that remains associated with a particular virtual function throughout the inheritance system.
Note: When the virtual function of the base class is not overwritten, the entity address of the function is copied to the virtual function table of the derived class.
In this way we realize the positive polymorphism of the implementation period. The characteristic of this form is that we do not know from beginning to end that the PTR pointer points to that object type, the base class? Derived Class 1? Derived Class 2? We don't know, and we don't need to know. We just need to know the virtual function table that the PTR points to. And we do not know that the entity of the Z () function is called, and we know only that the function address of the Z () function is positioned in the virtual function table.
Summary: In the system of single inheritance, the virtual function mechanism is a very efficient mechanism. We judge whether a class supports polymorphism, just by seeing if it has a virtual function. Well, that's it for today, Thor must speed up his study of the book, as if it could be faster now.