阅读:3640回复:1
DriverWorks里的SAFE_DESTRUCTORS是什么作用
DriverWorks里的说明如下,但小弟e文不佳而且汇编经验不足无法理解下面的话,请哪位大侠给翻译一下
//////////////////////////////////////////////////////////////////////// // Safe Destructors // // If a class does not explicitly define a destructor, the compiler // generates one if (1) a base class has an accessible destructor, or if // (2) a data member has an acessible destructor. // // The code section into which the compiler emits a destructor depends on // whether or not the destructor is virtual. If not, it goes in the same // section as the first code that references it. If it is virtual, it goes in // the same section as the first invocation of a constructor seen by the. // compiler. This is not documented, but it is the observed behavior of // MSVC++. ( In general, you can control the code section to which the // compiler emits code byusing #pragma code_seg("section-name") ). // // This behavior creates a problem if a compiler-generated destructor is // emitted to an INIT section. Attempting to invoke such a destructor after // the INIT sections have been discarded causes a fatal error. // // Note that the problem can occur even if all member functions of the // subclass (including constructors) are outside the INIT section. As long // as the first reference to the destructor is in the INIT section, the // problem arises. // // In the case where there is a virtual destructor in the base class, even // having the first reference to the destructor of the subclass outside of // the INIT section is not sufficient to avert the problem. The compiler // also generates a "scalar deleting destructor" and "vector deleting // destructor", and these will still be generated into the INIT section if // the constructor of the subclass is in that section, and there is no // prior invocation of the delete operator on the subclass outside the INIT // section. // // Furthermore, the "scalar/vector deleting destructors are also // generated in a non-optimized build for any class that has a destructor, // and an instance of it gets deleted. So even classes that have destructors // are subject to having the compiler generate additional destructor-related // code, which can fall into the wrong code section. // // To work around this problem, we recommend use of this macro: #define SAFE_DESTRUCTORS void _self_delete(void){delete this;} // Using this macro inside the definition of a class creates an in-line // reference to the destructor while the current code section is still // ".text" (assuming there is no #pragma code_seg(xxxx) ahead of the // include files). This is sufficient to cause the compiler to generate any // non-virtual destructors that it needs into ".text". For example: // // class MyDevice : public KDevice // { // SAFE_DESTRUCTORS // public: // MyDevice(whatever ...) // ... // }; // // NOTE: If you . . . // 1. want to have a virtual destructor, // 2. want to have a constructor in the INIT section, and // 3. you don't want the virtual destructor to be in the INIT section, // // Then you must have another constructor, which may be just a dummy, that // 1. is in the section in which you want the virtual destructor to be, and // 2. appears prior to the constructor in the INIT section in the // same source module // // As a general rule, you should always put the INIT section at the bottom // of the module. Also, remember that any subclasses of classes that have // virtual destructors will also have virtual destructors. // // Note that you can achieve functionality equivalent to virtual destructors by inserting the // word 'virtual' before the invocation of SAFE_DESTRUCTORS in a base class, and then // calling member _self_delete to delete an instance of the class or a subclass. The // subclass should define a non-virtual destructor and use SAFE_DESTRUCTORS. // // When should SAFE_DESTRUCTORS be used? Whenever the compiler might // generate a destructor, it's a good idea to use the macro. Remember that // even if a class defines its own destructor, the compiler may still // generate the "scalar/vector deleting destructors" which cause the same // result. Of course, it is always safe to use SAFE_DESTRUCTORS. It will // not cause any conflicts. // // The other problem to watch out for involves constructing arrays. Consider // the following code: // // #pragma code_seg("INIT") // void func1(void) // { // CSomeClass ClassArray[10]; // // .. // } // // #pragma code_seg() // void func2(void) // { // CSomeClass ClassArray[10]; // // .. // } // // In this case, the compiler-generated helper routine that constructs // the array of instances ends up in the INIT section. This causes a // fatal error if func2 is executed after the INIT sections have been // discarded. Correct this problem by reordering the functions within // the module. |
|
沙发#
发布于:2005-08-02 22:03
这个 e文不难了
自己看看把,也学学e文,其不是很好的事情 |
|
|