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.