.TH G_CODE 2 "3 May 1991" "Demeter" "Demeter Software" .SH NAME g_code \- generates C++ code that creates an identical copy of the object .SH SYNOPSIS char* .I g_code ( char* ); .br char* .I g_code ( ofstream& ); .br virtual char* .I g_code ( int&,ofstream& ); .SH DESCRIPTION .I g_code generates C++ code that makes, when executed, an instance of an object which is an identical copy of the object to which the message was sent. The code generated can then be integrated into a C++ program. The receiving object must be a tree object. That is, it cannot have any cycles or shared subobjects. .SH ARGUMENTS .RS 5.0 char* .I g_code ( char* ) .RS 6.0 The input argument is the name of the file you want to store the generated C++ code. .RE .RE .RS 5.0 char* .I g_code ( ofstream& ) .RS 6.0 The input argument is the .I ofstream variable to which you want to write the generated C++ code. .RE .RE .RS 5.0 virtual char* .I g_code ( int& idCnt,ofstream& ) .RS 6.0 .I g_code generates a number of temporary variables. The names for each of these variable start with "i" followed by the class name of an object and ends with a number. .I idCnt refers to this number. Every time g_code generates a variable, it will increment the value of this number. If you use .I char* g_code( ofstream& ), the number starts from 1. The second argument is the .I ofstream variable to which you want to write the generated C++ code. .RE .RE .SH RETURN VALUES .I g_code returns a character pointer that points to a string that contains the name of the variable where the copy of the object is stored. For example: Compound* iCompound = new Compound(); .br iCompound = (Compound*)iCompound->g_parse("demeter-input"); .br char* variableName = iCompound->g_code("code.c"); In file .I code.c, there is some C++ code to create an identical copy of Compound-object, iCompound. The address of the resulting object is assigned to the variable whose name is stored in .I variableName. Notice that as a side effect .I g_code will print the code to the stream or file with filename given. As a consequence, if you plan to use the returned value of .I g_code, namely .I variableName to print it to the same stream or file, you should be careful to first store the name in a variable and then print it, to give .I g_code time to do its printing and then return its value. The following example shows how NOT to use the value returned by .I g_code. Suppose the variable .I codeStream of type ostream is used to hold the stream of file .I code.c. Compound* iCompound = new Compound(); .br iCompound = (Compound*)iCompound->g_parse("demeter-input"); .br codeStream << "iCompound->g_equal(" .br << iCompound->g_code("code.c") // WRONG !!! .br << ");\en\&"; Here, the string "iCompund->g_equal" is printed first to the stream, then the side effect of .I g_code, and then the value of .I g_code, which is not what is intended. The correct way of doing it would be as follows. Compound* iCompound = new Compound(); .br iCompound = (Compound*)iCompound->g_parse("demeter-input"); .br char* variableName = iCompound->g_code("code.c"); .br codeStream << "iCompound->g_equal(" .br << variableName .br << ");\en\&"; // OK .SH REDEFINITION Since .I g_code with the interface .I char* g_code( int&,ofstream& ), is a virtual function, it can be redefined at any user class. This means that the user can change the code .I g_code generates for any particular object. As a technical consideration, making .I g_code virtual allows to define it recursively and to give the termination condition as a redefinition at the terminal classes DemIdent, DemNumber, DemReal, DemString, and DemText. .SH SEE ALSO g_parse(2), g_equal(2), terminal(2), g_copy(2) .SH REFERENCES .I User Manual for The C++ Demeter System .br Walter L. Hursch .br Northeastern University, 1993 .I The Annotated C++ Reference Manual .br Margaret A. Ellis and Bjarne Stroustrup .br Addison-Wesley, 1990 .I C++ Primer .br Stanley B. Lippman .br Addison-Wesley, 1989