|
Constructors are a feature of C++ (but not C) that make initialization of structures convenient. Within a structure type definition, define a constructor in a way that is similar to a function definition, with the following differences.
The name of the constructor must be the same as the name of the structure type.
Do not write a return type. The definition starts with the name of the constructor.
In the body of the constructor, refer to the fields by their names. Do not use a dot. The fields are implicitly those of the structure that is being initialized.
For example,
struct Cell { int item; char* name; Cell(int it, char* nm) { item = it; name = nm; } };defines type Cell with two fields and one constructor that takes two parameters.
You can use a constructor in three ways, which we illustrate for type Cell.
Cell c(20, "a cell");
This is equivalent to
Cell c; c.item = 20; c.name = "a cell";since the constructor definition's body says to do item = it; name = nm;where it and nm are the parameters. In general, writing parameters after a variable name in a statement that creates the variable runs the constructor with the given parameters after creating the variable. |
Cell* p = new Cell(20, "a cell");
Expression new Cell(it,nm) creates a new cell
in the heap and runs the constructor on that
new cell, with the given parameters. Its value
is a pointer to the new cell. Notice that,
in this case, the parameters are written after
new Cell, not after the name of the pointer
variable p.
Expression new Cell(it, nm) has type Cell*. |
Cell(20, "a cell");
Expression Cell(it, nm) creates a cell
in the frame of the current function and
initializes that cell.
The type of expression Cell(it, nm) is Cell.
You will not find this form very useful. Be careful not to confuse it with new Cell(it, nm), which yields a pointer (type Cell*) to a new cell that is in the heap. You might be tempted to write Cell c = Cell(20, "a cell");That works, but it asks to create a cell, initialize that cell, and then to copy that cell into c. The preferred way to do that is to initialize c directly: Cell c(20, "a cell"); |
The presence of a constructor does not alter the names of the fields. Type Cell above has two fields, called item and name. It does not make sense to write
Cell c; c.it = 34;since a Cell does not have a field called it. The constructor happens to have a parameter called it.
It is good practice to ensure that a constructor initializes all of the fields of a structured value. For example, the constructor for Cell initializes both of the fields, item and name, of a Cell.
It is not necessary for a constructor to have as many parameters as there are fields, but it often does. If you have fewer parameters than fields, you typically initialize some of the fields to default values.
If you define a constructor in the type definition, then you are required to use a constructor when you create a value of that type. For example, the definition of type Cell above has a constructor with two parameters. Statement
Cell c(20, "a cell");is allowed since it uses the constructor, but statement
Cell c;is not allowed because it does not use a constructor.
A structure type definition can include more than one constructor, as long as no two constructors have the same number and types of parameters. For example, an alternative definition of type Cell with three constructors is as follows.
struct Cell { int item; char* name; Cell(int it, char* nm) { item = it; name = nm; } Cell(int it) { item = it; name = ""; } Cell() { item = 0; name = ""; } };If there are multiple constructors then each time you create a structured value you must use one of the constructors. For example,
Cell a(16, "kangaroo"); Cell b(3);uses the constructor with two parameters to create a and the constructor with one parameter to create b.
To use a parameterless constructor, do not write ( ). For example,
Cell c;creates a Cell c and initializes it using the constructor with no parameters. Similarly,
Cell* p = new Cell;creates a new Cell in the heap and initializes that cell using the parameterless constructor. In C++, statement
Cell d();does not create a Cell at all. It is interpreted as a prototype for a function called d that takes no parameters and yields a result of type Cell.
If you create an array of a structure type, then each thing in the array is automatically initialized using the parameterless constructor. For example,
Cell A[10];creates an array of Cell values and initializes each of them using the parameterless constructor.
Note. If there is at least one constructor and no parameterless constructor then you are not allowed to create an array of structures of that type.
Note. An array of pointers is not automatically initialized. So
Cell* P[10];creates an array of uninitialized pointer variables. (The pointers are dangling until you store something into them.)
You are allowed to include something called a destructor, or also a deconstructor, in a structure type definition. Any time a structured value of that type is destroyed, either automatically or explicitly, the destructor is run on the structured value first. Typically, the destructor deallocates memory that is pointed to by pointers within the structured value. The destructor for type T is called ~T and always has no parameters. For example,
struct Vect { int size; int* arr; Vect(int n) { size = n; arr = new int[n]; } ~Vect() { delete [] arr; } };allocates an array when a Vect value is created and deallocates that array when the Vect value is destroyed (for any reason).
A complex number is represented by a pair of real numbers called its real part and its imaginary part. Define a structure type called Complex with two fields called impart and repart. Provide two constructors: one takes two parameters of type double and installs them into the two fields; the other takes no parameters and sets both fields to 0.0. Answer
Using type Complex from the preceding exercise, write a statement that creates a new complex number whose real part is 1.0 and whose imaginary part is 2.5. Call the new complex number z, and put it in the frame for the current function. Answer
Repeat the previous exercise, but this time allocate the complex number in the heap, and make z a pointer to it. Answer
If you create an array of Complex values, how are the values in the array initialized? Answer
Write a statement that creates variable zero of type Complex. Initialize it using the parameterless constructor. Answer
|