⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 csdn_文档中心_微软office的源代码样式规范(上) —— 绝对机密文档!!!.htm

📁 csdn10年中间经典帖子
💻 HTM
📖 第 1 页 / 共 5 页
字号:
            cItems) { m_cItems = cItems; }<BR>private:<BR>&nbsp;int 
            m_cItems;<BR>&nbsp;};</P>
            <P>Summary:<BR>&#61623; Data members use the naming convention m_name.<BR>&#61623; 
            Do not declare public data members.&nbsp; Use inline accessor 
            functions for performance.<BR>2.4 Virtual Functions<BR>Virtual 
            functions are used to allow derived classes to override a method in 
            a base class by providing their own implementation in a way that 
            always causes the most-derived version to be called whenever a 
            method is called through an object pointer, even if that pointer is 
            declared as a pointer to the base class.&nbsp; This is usually done 
            to implement polymorphism, and that抯 when we抣l use them.&nbsp; For 
            example, all COM interface methods are virtual because you are 
            always going for polymorphism via a standard interface.<BR>Unlike 
            simple member functions, virtual functions incur some overhead due 
            to need to call through the vtable.&nbsp; If a class contains at 
            least one virtual function then the data size of each instantiated 
            object will be 4 bytes larger than the combined size of the declared 
            data in order to hold the vtable pointer.&nbsp; After the first 
            virtual function, each additional one only adds another entry to the 
            class vtable, which is static and per-class (nothing per object), so 
            the main concern here is whether a class has any virtual functions 
            at all.&nbsp; In addition to the memory overhead, there is the 
            overhead to indirect a pointer twice before calling the 
            function.&nbsp; This is fairly fast and compact in 32-bit code, but 
            affects speed and size nevertheless. Perhaps the worst part is that 
            virtual functions cannot be inlined, so there will always be a 
            function call, even when the work is trivial.&nbsp; <BR>Because they 
            have overhead, you should not use virtual functions in a class 
            unless you need to.&nbsp; However, make sure you do use them when it 
            makes sense.&nbsp; In particular, if you have a base class which 
            requires a destructor, then the destructor should definitely be 
            virtual to allow derived classes to destruct any added members 
            properly.&nbsp; If the destructor were not virtual, then in a 
            context where polymorphism is being used (so the object pointer is 
            declared as a pointer to the base class), the base class destructor 
            will always get called, even for an object of a derived class that 
            added data members and declared its own destructor in an attempt to 
            free them.&nbsp; The derived class抯 destructor will only get called 
            if the base class destructor is declared virtual.&nbsp; This 
            scenario applies to many other kinds of methods that you will add to 
            your classes.&nbsp; In fact, most of the methods in a base class 
            might be this way if polymorphism is intended.&nbsp; This issues is 
            discussed in more detail in the Inheritance section below.<BR>Note 
            that although virtual functions have a performance penalty over 
            regular member functions, they are often the most efficient way to 
            implement a concept such as polymorphism where the alternative would 
            be large switch statements (not to mention the benefits of the 
            object-oriented encapsulation).<BR>Summary:<BR>&#61623; Use virtual 
            functions to implement polymorphism.<BR>&#61623; Virtual functions have 
            overhead, so don抰 use them unless you really should.<BR>&#61623; A 
            destructor in a base class should always be virtual if polymorphism 
            is intended.<BR>2.5 Constructors<BR>Ah, constructors.&nbsp; Every 
            new C++ programmer抯 nightmare.&nbsp; This is one reason to try to 
            minimize the use of constructors -- C programmers aren抰 used to them 
            and will get confused.&nbsp; Another reason is the infamous 
            performance overhead of calling a function (unless it抯 inline) and 
            doing work at possibly unexpected and/or redundant 
            times.<BR>However, using constructors can eliminate the dangers of 
            uninitialized data and can also made the code simpler to read (if 
            you抮e used to it).&nbsp; Judicious use of destructors (see below) 
            which match the constructors can also help prevent memory leaks and 
            other resource management problems.<BR>Fortunately, the issue is 
            mainly one when classes are declared on the stack or passed by 
            value, both of which we will avoid.&nbsp; Most of our classes should 
            be dynamic memory objects&nbsp; which will be passed around by 
            pointer.&nbsp; In this case, the constructor is essentially just a 
            helper function for the functions that create these dynamic 
            objects.&nbsp; Using a constructor for this purpose is reasonable to 
            ensure a clean and consistent initialization (if you make sure to 
            initialize all data members), but to prevent potential performance 
            problems due to redundant initialization the constructor should not 
            do anything expensive.&nbsp; Simply assigning a constant or a 
            parameter value to each data field is about right.&nbsp; Very simple 
            constructors can be made inline.&nbsp; <BR>Most importantly, a 
            constructor should never be able to fail, because lacking a fancy 
            exception handling mechanism, the caller has no way to handle this 
            in some cases.&nbsp; Any initialization that can fail (e.g. memory 
            allocations) should be put in a separate initialization member 
            function (called, e.g., FInit).&nbsp; When this is the case, it is 
            often useful to encapsulate the creation of an object in a function 
            (a global function or a member of another class) that calls new and 
            then FInit for the object, and returns the result of FInit.&nbsp; 
            For example:<BR>class Foo<BR>&nbsp;{<BR>public:<BR>&nbsp;Foo(int 
            cLines) { m_hwnd = NULL; m_cLines = cLines}<BR>&nbsp;virtual 
            ~Foo();<BR>&nbsp;BOOL FInit();<BR>&nbsp;void 
            DoSomething();<BR>private:<BR>&nbsp;HWND m_hwnd;<BR>&nbsp;int 
            m_cLines;<BR>&nbsp;};</P>
            <P>BOOL FCreateFoo(int cLines, Foo **ppfoo)<BR>{<BR>&nbsp;if 
            ((*ppfoo = new Foo(cLines)) == NULL)<BR>&nbsp;&nbsp;return 
            FALSE;<BR>&nbsp;if (*ppFoo-&gt;FInit())<BR>&nbsp;&nbsp;return 
            TRUE;<BR>&nbsp;delete *ppFoo;<BR>&nbsp;*ppFoo = 
            NULL;<BR>&nbsp;return FALSE;<BR>}</P>
            <P>BOOL Foo::FInit()<BR>{<BR>&nbsp;m_hwnd = 
            CreateWindow(...);<BR>&nbsp;return (m_hwnd != NULL);<BR>}</P>
            <P>Summary:<BR>&#61623; Do not do expensive work in a constructor.<BR>&#61623; If 
            you do make a constructor, make sure to initialize all data 
            members.<BR>&#61623; Very simple constructors can be made inline<BR>&#61623; A 
            constructor should never fail.&nbsp; Do memory allocations and other 
            potential failures in an FInit method.<BR>&#61623; Consider making a 
            creation function that encapsulates the new and FInit 
            operations.<BR>2.6 Destructors<BR>If a class has resources that need 
            to be freed, then the destructor is a convenient place to put 
            this.&nbsp; The normal case for us will be that this is just the 
            central place to free resources for an object that is freed via 
            delete (see below).&nbsp; The trickier use of destructors is for 
            stack-allocated classes, but we抮e going to avoid that by not using 
            classes on the stack.&nbsp; <BR>A destructor should be careful to 
            destroy an object properly regardless of how it was created or 
            used.&nbsp; Furthermore, if you choose to implement a method that 
            frees any resources before the actual destruction, make sure to 
            reset those fields (e.g. set pointers to NULL) so that a destructor 
            will not try to free them twice.&nbsp; It is not necessary for the 
            destructor to reset any fields, though, because the object cannot be 
            used after it is destructed.<BR>Like a constructor, a destructor can 
            never fail.&nbsp; Also, as stated above, a destructor in a base 
            class should always be declared virtual to make polymorphism 
            work.<BR>The destructor for the above example would be defined 
            as:<BR>Foo:~Foo()<BR>{<BR>&nbsp;if (m_hwnd != 
            NULL)<BR>&nbsp;&nbsp;DestroyWindow(m_hwnd);<BR>}</P>
            <P>Summary:<BR>&#61623; Use a destructor to centralize the resource cleanup 
            of a class which is freed via delete.<BR>&#61623; If resources are freed 
            before destruction, make sure the fields are reset (e.g. set 
            pointers to NULL) so that a destructor will not try to free them 
            again.<BR>&#61623; A destructor should never fail.<BR>&#61623; A destructor in a 
            base class should always be declared virtual if polymorphism might 
            be used.<BR>2.7 New and Delete<BR>The operators new and delete 
            should be used to allocate and free classes (instead of the 
            low-level malloc-like function in your app) so that the constructor 
            and destructor, if any are called properly.&nbsp; We will implement 
            our own global new and delete so that they in turn call our favorite 
            low-level memory manager, so the only difference is really that new 
            does the sizeof automatically and also calls a constructor, and 
            delete calls the destructor.<BR>Note that there must be some 
            mechanism for detecting failed memory allocations. For new, the 
            calling code is responsible for checking.&nbsp; Our memory manager 
            simply returns 0 for a failed allocation, and this will in turn be 
            returned from new (and the constructor will not be called).&nbsp; It 
            is therefore up to the caller of new to check for a 0 return value, 
            as in the example above in the Constructors section.<BR>You should 
            avoid defining any other new and delete (i.e. class-level) operators 
            and stick to the global one to avoid mixed memory models, which 
            complicates things like help optimization and memory leak checking 
            and makes it risky to have the routines that allocate and free a 
            block be different (although this is normally bad structure 
            anyway).<BR>Summary:<BR>&#61623; Use new and delete to allocate and free 
            classes.<BR>&#61623; We will implement our own global new and delete in 
            terms of the Office infrastructure memory manager.<BR>&#61623; Check the 
            return value of new for failure.<BR>&#61623; Avoid defining any other new 
            and delete operators (use the global ones defined by Office).<BR>2.8 
            Operators<BR>Ideally, you will never need to define an operator for 
            a class.&nbsp; If you did one, it might be operator=, but don抰 
            define one unless you really think you want this capability.&nbsp; 
            Next might be operator== and operator!=, but the same applies here, 
            only define them if really needed.&nbsp; We抮e not in the business of 
            providing a general class library that might be used in a certain 
            way, we抮e just implementing code that we actually expect to use 
            ourselves (as explained in a later section, we will not export a 
            real C++ class to anyone).&nbsp; And if you do define these 
            operators, make sure they are efficient so that you are not hiding 
            an expensive operation.<BR>By all means, never define standard 
            operators such as operator+ to do anything other than the standard 
            semantics for built-in objects.&nbsp; Don抰 even push it by doing 
            things like defining, say, operator+ to do a union or concatenation 
            operation.&nbsp; In addition to causing confusion, this hides 
            potentially expensive work behind an innocent-looking 
            operator.<BR>Summary:<BR>&#61623; Ideally, classes shouldn抰 need to define 
            any operators.<BR>&#61623; Define 搑easonable” operators such as =, ==, and 
            != only if you really want and use this capability yourself, and if 
            you do they should be super-efficient (ideally inline).<BR>&#61623; Never 
            define an operator to do anything other than the standard semantics 
            for built-in types.<BR>&#61623; Never hide expensive work behind an 
            operator.&nbsp; If it抯 not super efficient then make it an explicit 
            method call.<BR>&#61623; When in doubt, just make a member function to do 
            the work so that the operation is explicit.<BR>2.9 
            Inheritance<BR>Inheritance is a powerful technique, but it is often 
            misused and can lead to complex class hierarchies that are hard to 
            understand and hard to change.&nbsp; The following sections describe 
            the various uses of inheritance, compare them to other techniques 
            and try to provide rules of thumb about when to use it.<BR>Beyond 
            being appropriate in a particular case, however, just because 
            inheritance can be appropriate does not mean it should be used 
            everywhere.&nbsp; A deep or wide inheritance tree gets hard to 
            understand, hard to browse, and eventually hard to maintain.&nbsp; 
            Keep inheritance limited to a few 搒ilver bullets” where you really 
            win from it.<BR>Summary:<BR>&#61623; Don抰 use inheritance just because it 
            will work.&nbsp; Use it sparingly and judiciously.<BR>2.9.1 
            Inheritance of Interface vs. Implementation<BR>Most people think 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -