Obtain the member function address and function address

Source: Internet
Author: User

First, we define a class ctest, which contains three different forms of member functions, static member functions statfunc (), dynamic member functions dynfunc (), and virtual functions javasfunc (). In the main function, we use the cout standard output stream to output the addresses of the three functions respectively. The program is as follows:

# Include <iostream>
# Include <stdio. h>
Using namespace STD;

Class ctest
{
Public:
 Static void statfunc ()
 { Cout <"statfunc" <Endl;}

 Void dynfunc ()
 { Cout <"dynfunc" <Endl;}

 Virtual void extends func ()
 { Cout <"using func" <Endl;}
};

Void main ()
{
 Cout <"Address of ctest: statfunc:" <& ctest: statfunc <Endl;
 Cout <"Address of ctest: dynfunc:" <& ctest: dynfunc <Endl;
 Cout <"Address of ctest: commanfunc:" <& ctest: commanfunc <Endl;
 While (1 );
}

The screen output result is shown in:


It can be seen that the address of the static function is displayed normally. It is a 32-bit address value, but the address of both the dynamic function and the virtual function is output 1, which is obviously not the address value.

    To understand why, we must analyze the differences between these member functions in the running mechanism. We all know that static functions are independent of objects and belong to Classes. Therefore, we can call static functions through class calls (such as ctest: statfunc ()) it can also be called through an object (such as ctest
Object; object. statfunc ()). Both class call and object call correspond to the same function.

    However, dynamic functions can only be called through objects. Because in dynamic member functions, we usually need to change the Access Object members. We know that different objects of the same type have different copies of member variables in the class, so if a dynamic member function is called by a class, how do we know which object's member variable is accessed in the function. In addition, let's talk about the fact that dynamic function calls must be called through objects. Does it mean that dynamic member functions are bound to objects, is it true that the member functions called by different objects are different (Note: different member functions mean that the address stored in the function code is different, not that the function behavior is different ), so we need to output the address of the dynamic function, which must be obtained through the object, such as ctest
Object; & object. statfunc, which can be compiled on the compiler, can be found to be a programming error because the object can only be used to call a function and cannot be used to obtain the function address. Because we still need to get the function address through the class, dynamic functions are also bound to the class rather than the object. When calling a non-static member function, C ++ adopts a _ thiscall function call method. Using this call method, the compiler adds a pointer to call the member function in the called function parameter table during compilation, that is, the this pointer we often call. The call format is similar to ctest: dynfunc (ctest * This,
Otherparam ...), in the function body, the member variables or other member functions involved in the object are called using this pointer to process the data corresponding to the called object in the member function, without error processing of data of other objects. It can be seen that although we must call dynamic functions through objects, we actually access the same member function. Therefore, it is correct to use the & ctest: dynfunc class name to obtain the member function address. Dynamic functions are also bound to classes rather than objects.

     The cause of the error is that the output operator <does not overload the void (_ thiscall A: *) () type. The Compiler converts this type to the bool type, therefore, 1 is output. For static functions, the call method is not _ thiscall. <there is a heavy load on it. Therefore, static functions of the class can directly use the cout output function address. We can use printf for output, because it can receive any type of parameters, including the _ thiscall type, so we will
<"Address of ctest: dynfunc:" <& ctest: dynfunc <Endl; changed to printf ("Address of ctest: dynfunc: X \ n ", & ctest: dynfunc); shows the output:


You can read a book. By using printf output, we get the address of the dynamic function. So for the virtual function, we also use printf for output, is it OK? We will cout <"Address of ctest: Using FUNC:" <& ctest :: using func <Endl;
Change to printf ("Address of ctest: javasfunc: X \ n", & ctest: javasfunc). The output is as follows:


We can see that a quasi-address value can also be obtained.

To verify that the obtained address is correct, we can define three member function pointers to save the obtained function address, and then call the function pointer to check whether the output is correct, you can determine whether the obtained address is correct. The following is the verification code:

# Include <iostream>
# Include <stdio. h>
Using namespace STD;

Class ctest
{
Public:
 Static void statfunc ()
 {
  Cout <"statfunc" <Endl;
 }

 Void dynfunc ()
 {
  Cout <"dynfunc" <Endl;
 }

 Virtual void extends func ()
 {
  Cout <"using func" <Endl;
 }
};

Void main ()
{
 Ctest object;
 Ctest * pobject = & object;
 Cout <"Address of ctest: statfunc:" <& ctest: statfunc <Endl;
 Printf ("Address of ctest: dynfunc: X \ n", & ctest: dynfunc );
 Printf ("Address of ctest: Your FUNC: X \ n", & ctest: Your func );
 Static void (* p_statfunc )();
 Void (ctest: * p_dynfunc) (); // note that the non-static member function pointer must be defined in the class
 Void (ctest: * p_prop func )();
 P_statfunc = & ctest: statfunc;
 P_dynfunc = & ctest: dynfunc;
 P_prop func = & ctest: prop func;
 P_statfunc ();
 // The call of non-static member function pointers is also different from that of common functions. In addition, because the priority of. * is lower than that of (), you need to use brackets to put the operation on the left.

 // If it is written as object. * p_dynfunc (), compilation fails.

 (Object. * p_dynfunc )();

 (Object. * p_prop func )();
 While (1 );
}
After the code is run, it is shown as follows. From the output, we have successfully called the corresponding member functions:


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.