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.