class Matrix3x3 { public: float A[3][3]; void AddNum(float x) { .... } }; |
In fact, the situation is worse in C++, because C++ requires that array definitions contains constants
For example, this is NOT allows:
int N = 10; float A[N][N]; |
int N = 10; float *A; A = new float[N*N]; |
class MatrixNxN { int N; float *A; /* ------------------------------------------ CreateMatrix(n): reserve space for matrix ------------------------------------------ */ void CreateMatrix(int n) { A = new float[n*n]; // Reserve space for matrix N = n; // We must remember dimension // in order to access A[i][j] } /* ------------------------------------ AddNum(x): add number to matrix ------------------------------------ */ void AddNum(float x) { int i, j; for (i = 0; i < N; i = i + 1) for (j = 0; j < N; j = j + 1) A[i*N+j] = A[i*N+j] + x; }; } |
int main(int argc, char *argv[]) { int N; MatrixNxN M; N = 4; M.CreateMatrix(N); ... } |
The separation of the definition of the object M and the required invocation of M.CreateMatrix(N) create the possibility for PROGRAMMER ERROR:
  The program will not work if the programmer forgets to invoke M.CreateMatrix(N)   |
int main(int argc, char *argv[]) { int N = 4; MatrixNxN M(N); // Also reserve space for NxN matrix ... } |
A constructor must have the same name as the class itself.
class MatrixNxN { .... void CreateMatrix(int n) { A = new float[n*n]; N = n; } .... } |
class MatrixNxN { .... MatrixNxN(int n) // Constructor { A = new float[n*n]; N = n; } .... } |
MatrixNxN a; MatrixNxN A[3]; |
C++ provides a simple default constructor to you; but you can replace the provided default constructor with a more suitable one if necessary.
The default constructor provided by C++ will allocate space for all variables defined in a class.
class MatrixNxN { .... MatrixNxN() // DEFAULT Constructor: no parameters { .... } .... } |
int main(int argc, char *argv[]) { MatrixNxN f; .... } |
int main(int argc, char *argv[]) { MatrixNxN f(); .... } |
This definition will invoke the default constructor
A more explicit way to write this is: extern MatrixNxN f();, and I would encourage you to do this...
Copy constructor syntax 1:
class MatrixNxN { int N; float *A; ... } MatrixNxN a; ... (give components in ... "a" some value) MatrixNxN b(a); // Define b and // initialize b // with variable a |
Copy constructor syntax 2:
class MatrixNxN { int N; float *A; ... } MatrixNxN a; ... (give components in ... "a" some value) MatrixNxN b = a; |
C++ provides a simple copy constructor to you; and again, you can replace the provided copy constructor with a more suitable one if necessary.
The copy constructor provided by C++ will allocate space for all variables defined in a class and then copy all values in the supplied class variable to the new variable.
Hint: think about "call-by-reference"...
From the previous program, you can obviously see that the default copy constructor provided by C++ is inadequate to initialize a new MatrixNxN variable - because the new variable does NOT have its own array !!!
It is necessary to provide our own copy constructor.
The syntax to define a copy constructor is as follows:
class MatrixNxN { .... MatrixNxN(MatrixNxN & x) // Copy Constructor: // one MatrixNxN parameter { .... use x to initialize the new MatrixNxN variable } .... } |
int main(int argc, char *argv[]) { .... { int N; MatrixNxN M; N = 4; M.CreateMatrix(N); ... } } |
class MatrixNxN { int N; float *A; /* ---------------------------------------------- FreeMatrix(): free reserve space for matrix ---------------------------------------------- */ void FreeMatrix() { delete A; } ... (other stuff) } |
int main(int argc, char *argv[]) { .... { int N; MatrixNxN M; N = 4; M.CreateMatrix(N); ... M.FreeMatrix(); // You have to remember // to do this or your program // is toasted... !!! } } |
Relies completely on human's ability to "remember to do it"
There's gotta be a better way... and there is...
class MatrixNxN { .... void FreeMatrix() { delete A; } .... } |
class MatrixNxN { .... ~MatrixNxN() // Destructor { delete A; } .... } |
Recall the default copy constructor will copy ALL variables from one variable into the variable of another variable
That is when the copy constructor must copy values from variable OTHER THAN variables defined in the class
Such variables can only be allocated dynamically !!!
Consequently, when you destroy the class variable, you CANNOT simply use the default destructor;
You NEED to write a customized destructor to free the allocated memory !!!
  Whenever you define a COPY-CONSTRUCTOR in some class, you MUST define a DESTRUCTOR ALSO, and vice versa   |