Just as you can declare ordinary functions as based, you can also declare member functions as based. This is useful if you declare virtual functions as __near, which requires that they be called from within the same segment as they reside in. Note that a base class's definition of a function and a derived class's definition may reside in separate files.
For example, consider the following program:
// FILE 1 - Compiled under large model
class Shape
{
// ...
virtual void __near redraw();
}
void __near Shape::redraw()
{
// ...
}
void __far test( Shape *currShape )
{
currShape->redraw(); // Invoke virtual function
}
In this example, you can safely declare redraw as a near function, since it is in the same file as the function that calls it, and the compiler places it in the same segment. However, a derived class may be declared in another file, as follows:
// FILE 2 - Compiled under large model
class Circle : public Shape
{
// ...
void __near redraw();
}
void __near Circle::redraw()
{
// ...
}
Because this program is compiled under large model, each file defines a separate code segment. The test function cannot perform a near call to a redraw function in another segment. As a result, the test function may either succeed or fail, depending on whether its argument is an instance of a base class or an instance of a derived class. For example,
Shape my_shape;
Circle my_circle;
test( &my_shape ); // Okay - Shape::redraw in the same
// segment as the test function
test( &my_circle ); // Error - Circle::redraw in different segment
The second function call causes a run-time error.
The easiest way to avoid this problem is to declare all your virtual functions as __far, so they can be called from any segment. However, if you want to declare your virtual functions as __near, you can avoid problems by declaring the virtual function to be based in the same segment as test:
virtual void __near __based(__segname(“MYSEG”)) redraw();
void __far __based(__segname(“MYSEG”)) test( Shape *curr_shape );
The __based expression remains in effect through all subsequent redefinitions of redraw. Derived classes can define their own versions of redraw, and they will be stored in the same segment as the base class's version.
If redefinitions of a virtual function are declared as being based in a different segment, the compiler issues a warning.