11.15 Classes

  --------------

 

    11.15.1 Declaring functions in structures

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

 

        By adding support for declaration of functions in structures, a

    structure becomes similar to a class in C++, i. e., such a function

    becomes the method of a class. For example:

 

    struct Point // declaration of a class

    {

      int x; // element of data

      int y; // class of type Point

      void SetX(int);  // declaration of methods

      void SetY(int);  // class Point

    };

 

    void Point::SetX(int _x) //definition of a function of class Point

    {

      IF((_x>=0)&&(_x<=MAX_X)) x=_x;

    // variablea x, y are members of this class and thus access to it from

    // a function of this class is implemented directly

     }

 

    void main()

    Point p;  //define structure in stack

    {

      p.y = p.x = 0;

      p.SetX(1);

    }

 

        When calling a function which is a class method the address of this

    class (or structure) is transferred to it by the implicit method. The

    address is made accessible to the function via the name of the compiler

    variable 'this', automatically generated by the compiler. If the keyword

    'static' is included in the declaration of the function in the structure,

    the address of the class is not transferred to this function and the

    variable 'this' is not generated.

 

        A function declared in a structure may be dynamic. This is done by

    writing ':' at the very beginning of the declaration (the same

    as for ordinary dynamic functions). Such a dynamic function cannot

    be used as a macro.

 

 

    11.15.2 Inheritance

    ~~~~~~~~~~~~~~~~~~~~

 

        C-- supports simple and multiple inheritance. A structure with

    inheritance is declared as follows:

 

    struct Derived : Base1, Base2, ... Basen

    {

      int x0;

    };

 

        The number of base structures in the product is unlimited. In the

    case of multiple inheritance a structure can inherit two or more copies

    of a base structure. This leads to ambiguity:

 

    struct A

    {

      int x,y;

      . . .

    };

 

    struct B : A //structure 'B' inherits 'A'

    {

      . . .

    };

 

    struct C : A //structure 'C' inherits 'A'

    {

      . . .

    };

 

    struct D : B, C //structure 'D' inherits 'B' and 'C'

    {

      . . .

    };

 

    void main()

    D d;  //memory is allocated to structure 'D' in the stack and assigned the name 'd'

    {

      d.x0=0;

 

        In this example structure 'D" inherits two copies of structure 'A'

    and there are two variables in it named 'x0'. C++ compilers give an error

    message about records of type 'd.x0=0'. C-- processes this record and

    there is assignment by default to the element from the last base

    structure with 'x0'. Therefore, in order to gain access to the second

    'x0' (which is physically first in the structure) we need to execute an

    operation of permitting visibility:

 

      d.B::x0=0;

 

        It follows that:

 

      d.x0=0;

    and

      d.C::x0=0;

 

         are equivalent.

 

 

    11.15.3 Function inheritance

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

 

        If there is a function in a base class, and you redeclare this

    function in the derived class, it will be redeclared in the base class.

    Thus the function declared in the base class will be lost. For example:

 

    struct Point // base class

    {

      int x; // data elements

      int y; // class of type Point

      void SetX(int);  // declaration of methods

      void SetY(int);  // class Point

    };

 

    void Point::SetX(int _x) // definition of a function of class Point

    {

      IF((_x>=0)&&(_x<=MAX_X)) x=_x;

    }

 

    struct Point2 : Point // derived class

    {

      int x2;

    }

 

    struct Point3 : Point // another derived class

    {

      int z;

    }

 

    void Point3::SetX(int _x) // SetX is redefined in this derived class

    {

      IF((_x>=80)&&(_x<=MAX_X)) x=_x;

    }

 

        SetX, defined in the base class Point, is now inaccessible. Instead

    of the code defined in this class, the code of the function defined in

    the next class Point3 will be called. When SetX from the second derived

    class Point2 is called, the code of the function defined in the derived

    class Point3 will also be called. By thus redefining the function, you

    have changed the code of this function in the base class and in all its

    inherited classes.

 

        If needed for the code of the new function to be accessible at the

    same time as the code of the old function, one more declaration of this

    function must be made in the derived class:

 

    struct Point // base class

    {

      int x; // data elements

      int y; // class of type Point

      void SetX(int);  // declaration of methods

      void SetY(int);  // class Point

    };

 

    void Point::SetX(int _x) // definition of a function of class Point

    {

      IF((_x>=0)&&(_x<=MAX_X)) x=_x;

    }

 

    struct Point2 : Point // derived class

    {

      int x2;

    }

 

    struct Point3 : Point // another more derived class

    {

      int z;

      void SetX(int);  // one more declaration of SetX is made

                       // in the inherited class

    }

 

    void Point3::SetX(int _x) // SetX is redefined in this derived class

     {

      IF((_x>=80)&&(_x<=MAX_X)) x=_x;

      EDI=this;   EDI=this;

      EDI.Point.SetX(_x);  // call function of the same name from

                       // the base class

    }

 

        Now two different functions both named SetX are accessible from the

    derived class Point3. But only the base variant of SetX is accessible

    from the base class Point and from the second derived class Point2.