### Implementing Static Member Functions

Static member functions are specified in the interface definition or with an ACF. Those operations of an interface that the designer knows should be static have the static keyword before the operation in the interface definition file. For example, the newMatrix operation of the Matrix interface is designed to work without an invoking Matrix, so it could have been specified in the interface definition as a static member function as follows:

interface Matrix
.
.
.
static boolean newMatrix(...);

The IDL compiler automatically compiles this kind of operation as a static member function in both the server and client stubs. Depending on how a developer wants to implement the interface, it may be undesirable to commit to a static function. For example, the CreateMatrix( ) function described in the previous topic could have been specified as static in the interface, but it would prevent the server developer from directly using the built-in constructor feature of C++ to implement an object creator function. Therefore, to give maximum flexibility to both client and server developers, the static keyword can be left off the operation and then specified as needed in an ACF file.

Of course, creating new objects is just one thing a static member function can do, and so any number of other static member functions may be specified in the interface to do whatever application-specific work is required.

The Matrix interface declares the following operations:

Matrix * createMatrix(
[in] long v11,
[in] long v12,
[in] long v21,
[in] long v22
);
boolean newMatrix(
[in, out] long &rows,
[in, out] long &columns,
[out] Matrix ** m
);

The IDL compiler requires an ACF to implement these as static member functions. A sample server ACF contains the following:

/* FILE NAME: matrix.acf */
/* This file defines some attributes for the Matrix interface */
interface Matrix
{
/* include header files generated into the server stub */
[sstub] include "matrix_mgr";
/
/* createMatrix should be mapped as a creator function. */
/* The MatrixMgr is a class derived from the interface class. */
[cxx_new(MatrixMgr)] createMatrix();
/* newMatrix should be mapped as a static member function. */
[cxx_static] newMatrix();
}

[sstub] include
Use the include statement with the sstub attribute to make the IDL compiler include specific header files in the server stub. In this example, this is required so that the stub has a declaration of the manager class.

[cxx_new(MatrixMgr)] createMatrix( );
Use the cxx_new attribute with the name of the implemented manager class (MatrixMgr) as an argument, and apply it to the interface operation that is intended to create a dynamic object, createMatrix. This feature is described in the previous topic.

[cxx_static] newMatrix;Apply the cxx_static attribute to the names of all interface operations you intend to implement as static member functions.

To complete the story of a static function, the following is an example of one trivial implementation of the newMatrix function. The code implements only a 2 by 2 Matrix. If a client inputs values other than 2 for rows or columns, the values are changed to 2, and FALSE is returned.

// Implementation of the static member function declared with an ACF
idl_boolean
Matrix::newMatrix(idl_long_int &rows, idl_long_int &columns, Matrix **m)
{
if(rows != 2 && columns != 2) //implementing only a 2 by 2 Matrix
{
rows = columns = 2;
*m = 0;
return FALSE;
}
else
{
*m = new MatrixMgr(0, 0, 0, 0);
return TRUE;
}
}

The cxx_static attribute can also take an argument that represents a new name to use for the function. This may be necessary in your application if it needs to distinguish between remote and local versions of a static member function. In any case, to minimize changes to your code modules, it is a good idea to keep the implementation of static functions in files separate from the nonstatic member functions (the rest of the manager code). The following topic describes a common example of when to use an argument for the cxx_static attribute.

###