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

📄 chapter 9 designing classes.htm

📁 英文版编译器设计:里面详细介绍啦C编译器的设计
💻 HTM
📖 第 1 页 / 共 5 页
字号:
<P><PRE>      type
        A is class
          . . .
        end class;


        B is class
          extends A;
          . . .
        end class;
</PRE>It is important to remember that a hierarchy such as the one above refers 
only to instances of class B and and the symbolic representation of any instance 
of B. It does not try to represent all classes that inherit from B.
<P>
<H3>9.2.1 Single Inheritance</H3><!-------------------------------------------------------------------------------->As 
far as implementation is concerned, classes are in many ways similar to records. 
In fact, neglecting certain details, a class in memory looks exactly like a 
record. Consider a class like the one shown in listing {CLASSX} <PRE>      type
        X is class
          a: int;
          b: char;
          c: real;
        end class;

      <B>listing {CLASSX}.</B>
</PRE>The compiler would lay out such a class in memory in a manner similar to 
figure {CLSXMEM}. 
<MENU><IMG src="Chapter 9 Designing Classes.files/CLSXMEM.gif">
  <P><FONT face=arial size=-1><B>Figure {CLSXMEM}</B> A representation of the 
  way the members of a class are organized in memory. An integer takes four 
  bytes, a character one, and a real number takes eight.</FONT></P></MENU>The 
elements are stored contiguously in the order that they appear. This would be 
the same as for a record.
<P>Single inheritance refers to the types of hierarchies where each class within 
a hierarchy directly derives from no more than one superclass. In other words, A 
is subclassed by B, which is subclassed by C, which in turn is subclassed by D, 
and so on. Multiple inheritance refers to that type of inheritance where any 
class within a hierarchy derives from from more than one superclasses. See 
figure {SIMI}. 
<MENU><IMG src="Chapter 9 Designing Classes.files/SIMI.gif">
  <P><FONT face=arial size=-1><B>Figure {SIMI}</B> An example of the difference 
  between single and multiple inheritance. In multiple inheritance, the 
  hierarchy may have one or more branches.</FONT></P></MENU>The preferred method 
of implementing single inheritance is for the compiler to append the members of 
the deriving class onto the end of the base class. Suppose class Y derives from 
class X in figure {CLASSX}. <PRE>      type
        Y is class
          extends X;
          p, q: int;
        end class;

      <B>listing {CLASSY}.</B>
</PRE>The compiler would lay out each instance of Y like figure {CLSYMEM}. 
<MENU><IMG src="Chapter 9 Designing Classes.files/CLSYMEM.gif">
  <P><FONT face=arial size=-1><B>Figure {CLSYMEM}</B> An instance of class Y in 
  memory.</FONT></P></MENU>Single inheritance is easily implemented. In fact, some 
languages stop here due to the complexities of implementing further features. 
Most notable of these is Java.
<P>Inheritance immediately introduces one troublesome complexity: suppose class 
A inherits from class B, and both classes have an integer X. If we have an 
instance of A called a, which x do we get when we say a.X?
<P>This question is solved in two ways, both of which are strictly defined for 
SAL. The first is to make use of a special operator that works on classes, 
called the scope resolution operator. It is a double colon, ::. To answer the 
question posed, we can get at the X belonging to class A by saying a.A::X. We 
can likewise get to the X belonging to class B by saying a.B::X.
<P>The second solution is to rely on the order that members and methods shadow 
eachother. In SAL, the deriving class shadows the derived class. So when we say 
a.X, we implicitly mean a.A::X.
<P>
<H3>9.2.2 Multiple Inheritance</H3><!-------------------------------------------------------------------------------->When 
explaining single inheritance, we presented an implementation where the members 
of the subclass are appended to those of the superclass. This will not work in 
the case of multiple inheritance. When explaining multiple inheritance 
implementations, it is easier to think of a superclass being <I>included</I> in 
the subclass. Suppose we have a hierarchy where class C inherits directly from 
classes A and B. <PRE>      type
        A is class            //   A     B
          i, j: int;          //    \   /
        end class;            //     \ /
                              //      C
        B is class
          m, n: int;
        end class

        C is class
          extends A, B;

          p, q: int;
        end class;

      var
        c: C;
      
      <B>Listing {CLASSC}.</B>  Declaration for class A.
</PRE>An instance of class C will include the contents of classes A and B. In 
some languages this order is not defined. In SAL it is. Base classes are 
included in the same order that they are listed in the declaration for the 
deriving class. 
<MENU><IMG src="Chapter 9 Designing Classes.files/CLSCMEM.gif">
  <P><FONT face=arial size=-1><B>Figure {CLSCMEM}</B> The contents of classes A 
  and B are laid out consecutively at the beginning of each instance of class 
  C.</FONT></P></MENU>Again the issue of shadowing comes in to play, this time 
with a new twist. Suppose all three classes A, B, and C had a member integer 
called X. If we have an instance of class C, how do we know which class's X we 
are dealing with?
<P>Again, the question is solved in the same two ways as before. With scope 
resolution we can say c.A::X, and that will give us the member X of class A. We 
can say c.C::X, and that will give us the member X of class C. We can also 
explicitly designate the path to the variable that we want. c.C::A::X will give 
us the same thing as c.A::X.
<P>The second method is to rely on the order of shadowing. This order is 
strictly definde in SAL, though in some languages it is not. In SAL, the order 
of shadowing closely follows the order that base classes are listed in the 
declaration for any deriving class. In our example, for all instances of class 
C, all conflicting members of class A will shadow all conflicting members of B, 
since C derives first from A and then from B. Thus by default, if both A and B 
have a member X, c.X will give us the member X of A. If class C then also had a 
member X, c.X would implicitly give us the member X of class C.
<P>In multiple inheritance, and in some cases of single inheritance these two 
sloutions make use of eachother. In all cases, the order of scoping determines 
which members of which classes shadow the members of the other classes. Scope 
designation works by providing a hint in the process. In multiple inheritance, a 
superclass can appear more than once in a hierarchy. In all cases, a combination 
of judicious use of scope resolution and reliance upon the order of shadowing in 
all other cases will resolve ambiguities.
<P>
<H3>9.2.3 Shared Multiple Inheritance</H3><!-------------------------------------------------------------------------------->Shared 
multiple inheritance refers to that type of inheritance that in C++ is called 
virtual. In SAL we use the term shared instead of virtual, since the word 
virtual is a little overused.
<P>Among some OOP programmers, shared (virtual) inheritance is possibly the 
worst offense imaginable. Others agree that it is as necessary as a goto, in 
other words, to be used sparingly, with caution, and only when absolutely 
necessary. After an explanation of how this type of inheritance is implemented, 
we will see why.
<P>A graph representing a multiple inheritance hierarchy with virtual 
inheritance is shown in figure {MVI} 
<MENU><IMG src="Chapter 9 Designing Classes.files/MVI.gif">
  <P><FONT face=arial size=-1><B>Figure {MVI}</B> The difference between 
  multiple and shared multiple inheritance. a) B and C have their own instance 
  of A. b) B and C share a single instance of A.</FONT></P></MENU>In this scheme, 
both B and C inherit from class A. The question arises, if two base classes in 
their turn inherit from a common base class, do they each have their own copy, 
or do they share a single copy?
<P>C++ allows both types of inheritance, and so does SAL. In many cases, this 
question of whether or not a common base class is shared depends upon the design 
of the language, itself. C++ and SAL both obted for the maximum flexability. 
Other languages might shy away from shared-style multiple inheritance for the 
simple fact that is is adds an extra layer of complexity on top of a concept 
that is already a hairy and difficult matter.
<P>In SAL, subclasses must specify whether or not they intend to share a single 
copy of each superclass individually. Classes may not declare themselves as 
shared. Listing {UMI} shows an example of unique multiple inheritance, and 
listing {SMI} demonstrates the same classes using shared inheritance.
<P><PRE>      type
        A is class
          x, y: int;      //    A     A
        end class;        //    |     |
                          //    |     |
        B is class        //    B     C
          extends A;      //     \   / 
                          //      \ /  
          m, n: int       //       D   
        end class;

        C is class
          extends A;

          p, q: int
        end class;

        D is class
          extends B, C;

          i, j: int
        end class;

      <B>Listing {UMI}.</B>  Unique Multiple Inheritance


      type
        A is class
          x, y: int;
        end class;              //       A
                                //      / \
        B is class              //     /   \
          extends shared A;     //    B     C
                                //     \   /
          m, n: int             //      \ /
        end class;              //       D

        C is class
          extends shared A;

          p, q: int
        end class;

        D is class
          extends B, C;

          i, j: int
        end class;

      <B>Listing {SMI}.</B>  Shared Multiple Inheritance
</PRE>Member and method access rules have been strictly defined up to this 
point. All rules for the default order of scoping and scope designation still 
apply. The only new consideration is that there will be multiple paths to a 
single member or method within a shared group. This can introduce ambiguities 
that are not easily resolved without the use of these two utilities.
<P>

⌨️ 快捷键说明

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