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

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

📁 csdn10年中间经典帖子
💻 HTM
📖 第 1 页 / 共 5 页
字号:
            etc).  As a bonus, the debugger will even know about this 
            symbol.&nbsp; For example,<BR>// C++ solution:<BR>const DX dxMin = 
            0;&nbsp;// type safe, optimized, and debug symbol</P>
            <P>So true C++ constants are preferred to the traditional C++ 
            #define.&nbsp; Note that they cannot be used in shared C/C++ header 
            files, though, because a C compiler will just allocate memory for 
            them.<BR>C++ also makes the existing C concept of an enum type 
            safe.&nbsp; An enum in C++ defines a type and declares constants of 
            that type.&nbsp; You can then use that type as, say, a parameter to 
            a function, and the compiler can then enforce that you pass one of 
            the symbols defined in the enumeration (or you can type cast to get 
            around this if you need to).&nbsp; An enum can also be made local to 
            a class so that its scope is limited.&nbsp; For example,<BR>class 
            Foo<BR>&nbsp;{<BR>public:<BR>&nbsp;enum GMODE { gmNo = 0, gmYes = 1, 
            gmMaybe = -1 };<BR>&nbsp;void InsertGNode(GMODE gm);<BR>&nbsp;};</P>
            <P>Summary:<BR>&#61623; Use const or enum instead of #define for constants 
            that are only used in C++.<BR>3.2 References<BR>C++ adds the ability 
            to express references to objects, and the primary use of them is to 
            pass classes as parameters without the overhead of the copy 
            constructor being called.&nbsp; This is a worthy goal, but a more 
            straightforward method to do this is to just to pass classes by 
            pointer, which is what we抮e all used to from C.&nbsp; For someone 
            used to C, seeing something being passed by reference looks like it抯 
            being passed by value, so you might wonder if the constructor is 
            being called, or whatever.&nbsp; Furthermore, when using a 
            reference, the illusion is that you have a local copy of the object 
            that you can reference cheaply, but in fact you just have a pointer 
            to the object (this is how the compiler does it), and every access 
            is an indirection.&nbsp; We should just make this indirection 
            explicit by actually using pointers.&nbsp; Typing “*” or “-&gt;“ 
            instead of “.” is not a big deal, and it makes it more clear what is 
            going on.&nbsp; The one real advantage of references over pointers 
            is that they are guaranteed to be initialized (they cannot be NULL 
            or point to garbage).&nbsp; But this advantage is not worth the 
            above problems for us.<BR>Also note that when you do pass objects by 
            pointer, use const to mark formal parameters that are read-only (see 
            the "Const" section below).&nbsp; This is related to references 
            because some C++ programmers will use the convention that read-only 
            objects are passed by references and other objects are passed by 
            pointer (to make this safe you still need to the declare the 
            reference const because C++ will let you change a parameter through 
            a reference).&nbsp; This is a reasonable convention, but it still 
            has the problem of looking foreign and confusing to programmers with 
            a C background.&nbsp; So, we will use const to get the safety but 
            pass every object by pointer.<BR>There are other more exotic uses of 
            references, such as being able to return an lvalue from an operator 
            function, and sometimes this is necessary if you've defined such an 
            operator.&nbsp; But since we don抰 plan to use operators much if at 
            all (because we won抰 use stack-based classes), we should be able to 
            avoid references in most cases.<BR>Summary:<BR>&#61623; Avoid 
            references.&nbsp; Pass objects that are larger than an 搃nt” by 
            pointer.<BR>3.3 Const Parameters and Functions<BR>As mentioned 
            above, you should use const to mark formal parameters that are 
            read-only.&nbsp; This allows the compiler to check that you actually 
            obey this, serves as a form of documentation to users of your 
            function, and also allows the compiler to produce better code in 
            some cases.&nbsp; For example:<BR>/* Copy the contents of 'fooSrc' 
            into 'fooDst'. */<BR>void CopyFoo(const FOO *fooSrc, FOO 
            *fooDst);</P>
            <P>You can also declare non-pointer formal parameters as const (as 
            well as the actual pointer portion of a pointer parameter, rather 
            than what it points at, in which case the word "const" may appear 
            twice for that parameter), but this is not as much of a win and it 
            can make the prototype harder to read, so it's optional.&nbsp; This 
            just makes sure that you don't reuse the parameter itself as a local 
            variable and change its value.&nbsp; Of course, sometimes a function 
            will do this as a way of avoiding declaring and setting up a local 
            variable, so in this case you can't use const (not that this is not 
            great programming style, but we're not going to disallow it).&nbsp; 
            On the other hand, if you don't change the value of the parameter 
            within the function, declaring it as const may allow the compiler to 
            generate better code.&nbsp; Note that doing this does not give any 
            useful documentation to the caller, though.&nbsp; For example:<BR>/* 
            Copy 'cb' bytes of the contents of 'fooSrc' into 
            'fooDst'.<BR>&nbsp;&nbsp; In addition to not changing what 'fooSrc' 
            points at, my implementation<BR>&nbsp;&nbsp; promises not to change 
            the values of any of the local parameters<BR>&nbsp;&nbsp; within the 
            function (like you care...). */<BR>void CopyFooCb(const FOO *const 
            fooSrc, FOO *const fooDst, const int cb);</P>
            <P>In addition to declaring parameters const, you can also declare a 
            member function const to indicate that the function does not modify 
            the object.&nbsp; Again, this allows compiler checks and possible 
            optimization as well as a form of documentation.&nbsp; For 
            example:<BR>class Counter<BR>&nbsp;{<BR>public:<BR>&nbsp;int 
            CItems() const { return m_cItems; }<BR>&nbsp;void SetCItems(int 
            cItems) { m_cItems = cItems; }<BR>private:<BR>&nbsp;int 
            m_cItems;<BR>&nbsp;};</P>
            <P>Summary:<BR>&#61623; Use const to mark read-only pointer parameters 
            (what the pointer points at, not the pointer itself).<BR>&#61623; Use const 
            to mark member functions that don't change the object<BR>&#61623; Use const 
            to mark parameters themselves only if you care about the possible 
            performance gains in the implementation.<BR>3.4 Default 
            Arguments<BR>Having default arguments seems like a cool 
            feature.&nbsp; It seems like a way to add a parameter which only 
            some calls to a function will need to pass, so that the simple cases 
            will be kept simple.&nbsp; Well unfortunately, there is no 
            efficiency gain here, and instead the compiler is just hiding work 
            from you.&nbsp; If you have a function with one required argument 
            and four optional arguments, every call to this function will push 
            all five arguments, so you are getting the code size and time hit in 
            every case.&nbsp; Furthermore, you can抰 even use default arguments 
            just to try something new without bothering with the old calls 
            because you still have to find all the old calls in order to rebuild 
            those files (if you do an incremental build of just one use after 
            adding a default argument, the other calls will screw up).&nbsp; 
            Finally, default arguments can be easily confused with overloading 
            (which we抣l also avoid).<BR>There are cases, however, where a 
            certain parameter is totally irrelevant in a call (because, for 
            example, the value of another parameter tells you all you need to 
            know).&nbsp; Note that this is somewhat different from a default 
            argument because there is no real default value for this 
            parameter.&nbsp; In these cases, it is nice to have the untyped 
            constant "NA" , #defined to be 0, to stand for "Not applicable" 
            which can be passed to indicate this for any actual parameter.&nbsp; 
            This is better than passing, say, NULL for a pointer or FALSE for a 
            Boolean because it makes it clear that the value is not important at 
            all.&nbsp; For example:<BR>#define NA&nbsp; 0&nbsp;&nbsp;// 
            universal "not applicable" parameter value</P>
            <P>/* If fShow then show the object, else hide it.&nbsp; If showing 
            then<BR>&nbsp;&nbsp; redraw it only if fRedraw.<BR>void Show(BOOL 
            fShow, BOOL fRedraw);</P>
            <P>void Ack()<BR>{<BR>&nbsp;Show(TRUE, 
            TRUE);<BR>&nbsp;...<BR>&nbsp;Show(FALSE, NA);<BR>}</P>
            <P>Summary:<BR>&#61623; Don't use default arguments.<BR>&#61623; Use "NA" 
            (#defined to be 0) for "not applicable" parameters in a call.<BR>3.5 
            Function Overloading<BR>Overloading functions is just a lazy naming 
            scheme.&nbsp; It seems like a form of polymorphism, but it shouldn抰 
            be confused with real polymorphism because all the decisions must be 
            made staticly at compile time.&nbsp; It抯 just a way to keep 搒imple” 
            function names and reuse them for different cases.&nbsp; Such a lazy 
            naming scheme just causes more confusion than it抯 worth (trying to 
            determine which function is relevant, changing the wrong one by 
            accident, etc.) and can also interfere with proper use of Hungarian 
            in some cases.&nbsp; Finally, the combination of function 
            overloading and type coercion can be quite confusing 
            indeed.<BR>Summary:<BR>&#61623; Don抰 overload functions<BR>3.6 Operator 
            Overloading<BR>The main use of operators is in classes.&nbsp; This 
            is discussed in a previous section.&nbsp; Operators can also be 
            overloaded at global scope.&nbsp; For example, you can define what 
            operator+ should do when it finds a Foo on the left side and a Bar 
            on the right side.&nbsp; Unlike the use within a class, this allows 
            control over the left-hand side operand.&nbsp; Anyway, all the same 
            problems apply and more (due to the larger scope). Functionality is 
            hidden (a possible efficiency problem) and confusion can result, so 
            we will avoid this.<BR>Summary:<BR>&#61623; Don抰 overload operators, 
            especially at global scope.<BR>4. Common C/C++ Issues<BR>The 
            following sections comment of features of regular C that we also try 
            to maintain a consistent use of.<BR>4.1 #ifdefs<BR>First and 
            foremost, everyone should try really hard to minimize the use of 
            #ifdefs.&nbsp; Programs with lots of #ifdefs are really hard to 
            read.&nbsp; It is often possible to either invent the right 
            abstraction or to isolate the #ifdefs to small places in header 
            files, or make the right definitions in target-specific headers so 
            as to make #ifdefs unnecessary in the main code.&nbsp; The main 
            argument for #ifdefs (over, say, a regular 搃f”) is to minimize the 
            code size.&nbsp; However, everyone should be aware that the 
            optimizer is perfectly capable of simplifying statements that 
            evaluate to a constant.&nbsp; For example,<BR>// Wrong:<BR>#ifdef 
            MAC<BR>if (x == 3 || Foo() || FSomeMacMode())<BR>#else<BR>if (x == 3 
            || Foo())<BR>#endif</P>
            <P>// Right:<BR>// In a header file for each non-Mac platform, there 
            is<BR>#define FSomeMacMode()&nbsp;FALSE</P>
            <P>// Then the using code can just be <BR>if (x == 3 || Foo() || 
            FSomeMacMode())</P>
            <P>In this example, the compiler is perfectly capable of eliminating 
            what amounts to (搢| FALSE”) at compile-time.&nbsp; Furthermore, if 
            the entire "if" were to always evaluate to FALSE at compile time, 
            then the optimizer will also remove all of the code inside the "if" 
            and remove the test.<BR>If you must use an #ifdef, we prefer to use 
            #if instead because it's shorter and allows logical operations, as 
            in:<BR>int Foo()<BR>{<BR>&nbsp;int x = 3<BR>&nbsp;#if MAC &amp;&amp; 
            !DEBUG<BR>&nbsp;&nbsp;x = 0;<BR>&nbsp;#endif<BR>&nbsp;return 
            x;<BR>}</P>
            <P>Note that we will still leave flags such as DEBUG undefined when 
            false, but the compiler does the right thing here (treats it the 
            same as being defined to be 0).&nbsp; Leaving these flags undefined 
            means that #ifdef will also work, in case this is used by accident 
            anywhere.<BR>Also, as this example shows, #ifs should be properly 
            indented so that they read easily when nested.&nbsp; Yes, this 
            works;&nbsp; C Compilers have accepted this for years.<BR>Aside from 
            the standard identifiers defined by our build process (e.g. DEBUG, 
            MAC), we will also use the identifiers UNUSED and LATER, which are 
            never defined, to mark code which is currently unused but kept in 
            for some reason, and code which cannot be activated yet but will 
            eventually, respectively.<BR>Summary:<BR>&#61623; Minimize #ifdefs by 
            defining good abstractions, partitioning fil

⌨️ 快捷键说明

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