调试C++NPv2_TP_Reactor_Log_Server程序
main函数中定义ACE_TP_Reactor tp_reactor;变量,定义在ace\TP_Reactor.h文件中的类ACE_TP_Reactor继承ACE_Select_Reactor类,例子C++NPv2_Select_Reactor_Log_Server的main函数中定义了ACE_Select_Reactor select_reactor;变量,类ACE_Select_Reactor则是在ace\Select_Reactor.h文件中定义:typedef ACE_Select_Reactor_T<ACE_Reactor_Token_T<ACE_Token>> ACE_Select_Reactor;,其中ace\Select_Reactor_T.h文件中定义了模板类ACE_Select_Reactor_T;ace\Reactor_Token_T.h文件中定义了模板类ACE_Reactor_Token_T,ace\Token.h文件中定义了类ACE_Token。
调试C++NPv2_TP_Reactor_Log_Server例子,ace\OS_main.h文件中的宏扩展了main函数,其中定义了继承自ACE_Main_Base类的ACE_Main类,main函数中定义ACE_Main m;变量,ACE_Main_Base的构造函数中调用ACE::init函数,该函数中调用ACE_Object_Manager::instance来构造ACE_Object_Manager对象,ACE_Object_Manager类构造函数中调用其成员函数init,在该函数中调用ACE_Atomic_Op<ACE_Thread_Mutex, long>::init_functions函数,在ACE_Atomic_Op<ACE_Thread_Mutex, long>::init_functions函数中,对其静态成员变量increment_fn_赋值,这些变量为函数指针,因为这些变量是静态变量,在实现文件中先会对其赋值,对函数指针赋值可以直接将一个函数名取地址赋值给函数指针,但是这里是直接将函数名作为值赋值给函数指针的解引用,其实是一样的。
VS2013实现发现对一个函数指针变量,将一个函数名取地址后赋值给该变量,或者直接将该函数名赋值给该指针变量,通过对该指针解引用调用都可以正常执行,效果一样。测试发现对函数指针解引用调用或者直接将函数指针作为函数名调用,结果是一样的。
关于类的成员函数指针类型,如果对一个函数指针赋值,必须对这个非静态函数加上&,即取地址符。否则会以为是调用该函数,报错说"XXX函数调用缺少参数列表,用&XXX创建一个成员指针"。但是如果该函数是一个类的静态函数,则需要一个一般函数的指针来指向,就不需要加上取地址符&了。这个主要是调用博客园上的文章<一般函数指针和类的成员函数指针>的第二部分指向类的成员函数的指针发现的:类的静态成员函数采用与一般函数指针相同的调用方式。
关于类成员函数指针的调用:->*和.*。在文章<一般函数指针和类的成员函数指针>中,用的是->*操作符,这样的方式在ACE的例子中也可以看到,ace\Event_Handler_T.h文件中定义了模板类ACE_Event_Handler_T,该模板类中定义了类成员函数指针类型GET_HANDLE、SET_HANDLE、IO_HANDLER等,同样以这些函数指针类型定义了成员变量,以及模板类型的指针T *op_handler_;。在examples\Reactor\Misc\test_event_handler_t.cpp文件中进行测试,该文件中定义了ACE_Test_Sig_Handler类作为模板类ACE_Event_Handler_T的模板实参,并将模板实参类ACE_Test_Sig_Handler的成员作为参数来定义ACE_Event_Handler_T模板类的对象,即赋值给ACE_Event_Handler_T模板类中定义的类成员函数指针,然后又由于该模板类中定义了模板实参指针T *op_handler_;(//Pointer to the object that handles all the delegated operations),所以在调用时用->*操作符,具体见ace\Event_Handler_T.cpp文件中的ACE_Event_Handler_T<T>::get_handle等模板函数。->*的左侧是一个类对象的指针,而->*的右侧则是一个类成员函数指针的对象,是一个变量,这个变量即成员函数指针对象指向一个类的成员函数指针。关于类成员函数指针.*参看ace\Select_Reactor_Base.cpp文件,在该文件的ACE_Select_Reactor_Impl::bit_ops函数中,首先定义了类成员函数指针ACE_FDS_PTMF ptmf = &ACE_Handle_Set::set_bit;,在后面通过一个类对象,而非类对象指针来调用时就用.*操作符。
网上搜到一篇文章<typedef定义函数类型>,该文章中用typedef分别自定义函数指针类型及自定义函数类型。区别就是当自定义函数类型时,需要像内置类型那样定义一个指针来指向某一函数。在第一个例子中,即tpyedef自定义函数指针类型,定义了一个指针类型,然后用该类型创建一个变量,即指针变量,但是该例子中对指针变量赋值的时候并没有用函数名取地址,而是直接用函数名来赋值,后来测试用函数名取地址也可以赋值给函数指针变量,然后函数指针变量可以解引用调用也可以直接调用,结果都一样。
关于用typedef对一个类的成员函数指针类型的声明,与普通成员函数指针类型声明类似,只不过在类型前加上"类名::",对于一个类的静态函数,可以将其取地址后赋值给一个普通的函数指针。这个可以在ACE_Object_Manager::init函数中看到,当调用完ACE_Atomic_Op<ACE_Thread_Mutex, long>::init_functions ()函数后,会以&ACE_Service_Config::handle_signal作为参数构造ACE_Sig_Adapter类对象,handle_signal函数为ACE_Service_Config类的静态函数,而ACE_Sig_Adapter类的构造函数中对应该静态函数的类型ACE_Sig_Handler_Ex则为普通的函数指针类型。
不理解main函数中auto_ptr<ACE_Reactor> delete_instance变量定义的意义。