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

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

📁 csdn10年中间经典帖子
💻 HTM
📖 第 1 页 / 共 5 页
字号:
            about inheritance as a way to share code.  However, one of the 
            most useful ways to use it is simply as a way to ensure working 
            polymorphism by inheriting interface only.  The classic example 
            is to have an interface class which is entirely abstract (all 
            methods are pure virtual), and then one or more implementation 
            classes that inherit the interface and implement it in different 
            ways.  The OLE COM model is an example of this.  A COM 
            interface is expressed in C++ as an abstract base class, and then a 
            separate implementation class inherits from the interface class and 
            implements the interface methods for that object.  Here the 
            inheritance is simply a convenient way to ensure that the object 
            speaks the exact interface it is supposed to (has the right methods 
            in the right order in the vtable with the right parameters and the 
            right return types).  This is ensured by having each 
            implementation class inherit from the same interface class, which is 
            only declared once in a common header file.  Note than when an 
            interface class implements an inherited pure virtual method, it must 
            redeclare it because from a language point of view, it is still 
            considered to 搊verride” the base method.&nbsp; For example:<BR>// 
            The interface base class provides interface only<BR>class 
            FooInterface<BR>&nbsp;{<BR>public:<BR>&nbsp;virtual void DoThis() = 
            0;&nbsp;&nbsp;// pure virtual<BR>&nbsp;virtual void DoThat(int i) = 
            0;&nbsp;// pure virtual<BR>&nbsp;};</P>
            <P>// The implementation class implements the FooInterface 
            interface<BR>class FooImplementation: public 
            FooInterface<BR>&nbsp;{<BR>public:<BR>&nbsp;virtual void 
            DoThis();<BR>&nbsp;virtual void DoThat();<BR>&nbsp;}</P>
            <P>void 
FooImplementation::DoThis()<BR>{<BR>&nbsp;...<BR>}<BR>...</P>
            <P>The above example shows the case where the entire base class is 
            interface only.&nbsp; However, inheritance of interface only can 
            also happen at the level of an individual member function in a base 
            class which also includes some implementation.&nbsp; This is the 
            case when any member function is declared pure virtual.&nbsp; An 
            example of this is shown below with the DrawObj::Draw method.<BR>The 
            above example does not use inheritance to share code.&nbsp; However, 
            inheritance can also be used for this, and this is done by providing 
            implementations of methods in a base class that inherited classes 
            can use.&nbsp; There are two interesting cases here.&nbsp; If the 
            base class defines an implementation of a method which can either be 
            used or overridden, then the base method is defining an interface 
            with a default implementation.&nbsp; In this case, the method should 
            be defined as virtual so that any class which overrides the method 
            will get the right result when polymorphism is used.&nbsp; 
            Alternately, if the base class method provides an implementation of 
            a method which is not meant to be overridden (because it does a 
            standard action on data which is private to the base class), then 
            the base method is defining an interface and a required 
            implementation.&nbsp; In this case, the method should not be 
            declared virtual.&nbsp; The converse of this is that when inheriting 
            from a class, do not override any non-virtual functions because this 
            could lead to maintenance problems when the base class is 
            changed.<BR>In general, the two cases of inheritance of 
            implementation outlined above as well as the case of inheritance of 
            interface only can all be combined in a single class by having 
            different methods do different things.&nbsp; The key is to decide, 
            for each method, whether the goal of the base method is to provide 
            interface only, interface plus default implementation, or interface 
            plus required implementation.&nbsp; For example:<BR>// A base class 
            for drawing objects<BR>class 
            DrawObj<BR>&nbsp;{<BR>public:<BR>&nbsp;virtual void Draw() = 
            0;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 
            interface only<BR>&nbsp;virtual BOOL FHitTest(POINT pt);&nbsp; // 
            default implementation<BR>&nbsp;void GetBounds(RECT 
            *pr);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // required 
            implementation<BR>private:<BR>&nbsp;Rect m_rBounds;&nbsp;// bounding 
            rectangle<BR>&nbsp;};</P>
            <P>BOOL DrawObj::FHitTest()<BR>{<BR>&nbsp;return PtInRect(pt, 
            m_rBounds);<BR>}</P>
            <P>void DrawObj::GetBounds(RECT *pr)<BR>{<BR>&nbsp;*pr = 
            m_rBounds;<BR>}</P>
            <P>In this example, the Draw method is pure virtual because it is 
            only specifying an interface for polymorphic use.&nbsp; Any derived 
            class that can be instantiated must define the Draw method.&nbsp; 
            The FHitTest method is defining interface (for polymorphism) as well 
            as a default implementation.&nbsp; Any derived classes that don't 
            need non-rectangular hit-testing can just use the default 
            implementation (no code or declaration required), but other classes 
            can simply override this method and do special hit-testing.&nbsp; 
            The GetBounds method is an example of a required 
            implementation.&nbsp; The base class requires that "bounds" be 
            defined in the same way for all objects, and it doesn't make sense 
            for anyone to change it.&nbsp; In this case, the member does not 
            need to be virtual (and should not be for clarity and efficiency) 
            because the base class implementation is always 
            used.<BR>Summary:<BR>&#61623; Inheritance of interface can be used for 
            ensuring a consistent (e.g. polymorphic) interface.<BR>&#61623; An 
            implementation class can inherit its interface from an interface 
            class where the interface class has only pure virtual methods.<BR>&#61623; 
            When using inheritance of implementation to share code in a base 
            class,<BR>&nbsp;&nbsp;&#61623;&nbsp; Use pure virtual functions to provide 
            interface only.<BR>&nbsp;&nbsp;&#61623;&nbsp; Use virtual functions to 
            provide interface and a default 
            implementation.<BR>&nbsp;&nbsp;&#61623;&nbsp; Use non-virtual functions to 
            provide interface and a required implementation.<BR>2.9.2 
            Inheritance vs. Containment<BR>The most common misuse of inheritance 
            is to view inheritance as a way to share code among 搒imilar” objects 
            and to use it in a context where there is no real 搃s a” 
            relationship.&nbsp; There are several ways to share code, and the 
            simpler technique of containment and delegation (one class contains 
            another and delegates the relevant functionality to it), which we抮e 
            all used to from traditional structured programming, works fine in 
            most cases.&nbsp; In this case, the relationship is described as 揾as 
            a”.<BR>The primary reason to use inheritance instead of containment 
            is to achieve polymorphism (in conjunction with the use of virtual 
            functions).&nbsp; The easiest way to test for an 搃s a” relationship 
            is to think whether polymorphism is what is desired.&nbsp; If so, 
            then inheritance could be appropriate (assuming any other practical 
            concerns are met).&nbsp; Another way to test 搃s a” vs. 揾as a” is to 
            ask yourself if it could make sense to have more than one of the 
            base class in the derived class.&nbsp; If so, then 揾as a” 
            (containment) is the right model.&nbsp; For example, if you were 
            implementing a scrolling window and you already have a scrollbar 
            class, you would notice that a window could have two scrollbars 
            (horizontal and vertical) even if you weren抰 planning on that 
            feature in the first version, so a window should contain (揾as”) a 
            scrollbar, not inherit from (搃s”) one.&nbsp; <BR>Even when you do 
            decide to use inheritance from another class, it is often the case 
            that you should split the original class into a base class and a 
            derived class and inherit only from the base class.&nbsp; This 
            allows you to split off only the stuff that is really shared.&nbsp; 
            For example, say you had a Rectangle drawing object, and now you 
            want an 揙val” object.&nbsp; You convince yourself that polymorphism 
            is desired (e.g. drawing and hit-testing code in the caller wants to 
            treat all objects the same), and that an Oval would never want two 
            Rectangles.&nbsp; Now you might decide to have the Oval inherit from 
            the Rectangle, but probably what you really want is to split the 
            Rectangle class into a base DrawingObject class and a separated 
            derived Rectangle class, and then Oval would inherit from 
            DrawingObject, not Rectangle.&nbsp; This allows later changes to the 
            Rectangle object that are specific only to it, even if this isn抰 
            needed now.&nbsp; As in the example from the previous section, the 
            DrawingObject base class will probably have a combination of pure 
            virtual methods to enforce the polymorphic interface, virtual 
            methods to provide a standard interface as well as a default 
            implementation for all 搒imple objects”, and non-virtual methods to 
            provide required implementation of stuff that is common to all 
            objects and assumed to be constant in the common code.<BR>Note that 
            containment forces you to use the contained object抯 public 
            interface, whereas inheritance allows use of protected members 
            also.&nbsp; This is another way of saying that containment is more 
            encapsulated than inheritance.&nbsp; In fact, it is often said that 
            inheritance breaks encapsulation because it can create dependencies 
            on the implementation of the base class.&nbsp; This is particularly 
            true in the case of overridden functions, where a change to the base 
            class might not have the right effect on all derived 
            classes.<BR>Summary:<BR>&#61623; Be careful with inheritance vs. 
            containment.&nbsp; When in doubt, use containment.<BR>&#61623; Inheritance 
            is an 搃s a” relationship, whereas containment is a 揾as a” 
            relationship.<BR>&#61623; Test for 搃s a” by seeing if polymorphism is 
            desired or makes sense.<BR>&#61623; Test for 揾as a” by asking yourself if 
            one class could ever use more than one of the other class.<BR>2.9.3 
            Multiple Inheritance<BR>We will avoid multiple inheritance 
            altogether.&nbsp; Multiple inheritance has a number of problems 
            including resolution of name conflicts, efficiency concerns of some 
            operations (functionality is hidden from you), maintenance problems, 
            and general confusion about what the heck is going on.<BR>If you are 
            building a large and complex inheritance hierarchy (to be avoided as 
            noted above), you might find yourself wanting multiple inheritance 
            to share code from two different places. In the case of literally 
            sharing code from two different places, this is the most dangerous 
            form of multiple inheritance because it leads to the trickiest 
            dependencies.&nbsp; There are other forms of multiple inheritance, 
            though.&nbsp; The safest is multiple inheritance of only interfaces 
            (no code from any base class), but even this has problems with 
            things like name conflicts.&nbsp; So, we will avoid it altogether. 
            <BR>Every time you think you need multiple inheritance, you should 
            consider that maybe you are over-using inheritance and you should 
            switch to containment in some cases.&nbsp; Inheritance is a silver 
            bullet that you have only one of.&nbsp; Once you抳e used it for a 
            given class, you need to use containment to get anything else.&nbsp; 
            Note that you can use containment as much as you want within a given 
            class with no problems.<BR>Summary:<BR>&#61623; Don抰 use multiple 
            inheritance.<BR>&#61623; Given only single inheritance, inheritance is a 
            搒ilver bullet” which you have only one of, so use it sparingly and 
            judiciously.<BR>3. Other C++ Features<BR>The following sections 
            comment on various new features of C++ that aren抰 directly related 
            to classes.<BR>3.1 Constants and Enumerations<BR>C++ adds the 
            concept of true constants to C.&nbsp; In C, you had the choice of 
            using a #define or declaring a "const" global variable.&nbsp; 
            However, the #define will not be type safe, and the const variable 
            takes up real memory and isn't optimized.&nbsp; For example:<BR>// C 
            alternatives:<BR>#define dxMin&nbsp; 0&nbsp;&nbsp;// not type 
            safe<BR>const DX dxMin = 0;&nbsp;// just a real global variable</P>
            <P>In C++, the const syntax declares a real constant of the 
            specified type that the compiler will type-check, and then 
            substitute the actual value in-line and optimize (fold constants, 

⌨️ 快捷键说明

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