In C you declared a constant using the #define statement. For example, to specify that the boiling point of water is 212 degrees, you might have written:
#define WATER_BOILING_POINT 212
In C++ you declare a constant using the const keyword. For example:
const int WATER_BOILING_POINT = 212;Notice that a constant declaration requires five elements:
The constant keyword can be used to declare local variables, global variables, or parameters to be constant. For example, the function declaration:
float compute_avg(const int scores [], const int size);declares that both the scores array and the size of the scores array are constant within the function. That means that within the function you promise not to modify either the contents of the scores array or the size variable. If you attempt to do so, the compiler will give you an error message. For example:
#include <stdio.h>
float compute_avg(const int scores[], int size) {
int i, sum;
sum = 0;
for (i = 0; i < size; i++) {
sum += scores[i];
scores[i] = sum; // can't do this--scores is a constant
}
return ((float)sum / size);
}
main() {
int s[5] = {72, 68, 79, 81, 65};
printf("%6.2f\n", compute_avg(s, 5));
}
|
If you try to compile this program, you get the following error message from the compiler:
UNIX> g++ temp.cc avg.cc: In function `float compute_avg(const int *, int)': avg.cc:8: assignment of read-only location
We will try to avoid using reference types in this class because they are confusing. However, they appear in examples in both the Weiss and Schildt books and therefore you need to have at least a basic understanding of what they are. For example, if you have a class named string, you will often see a method with the following signature:
string::string(const string &objToBeCopied);This method is called a copy constructor and we will talk about it later in these notes. The thing to focus on for now is the declaration of the parameter objToBeCopied:
You have already seen how constructors are used to initialize an object when it is first created. Here are some specifics to remember about constructors:
class Stack {
protected:
int *data;
int top;
public:
Stack( int maxSize );
Stack( );
...
};
Stack::Stack( int maxSize ) {
top = 0;
data = new int[maxSize];
}
Stack::Stack( ) {
top = 0;
data = new int[20]; // default maximum size
}
|
~Stack() { delete [] data; }
|
Stack a(5);
Stack b;
Stack c(a);
Stack *x = new Stack(4);
Stack *y;
Stack *z = new Stack[5]; // allocate an array of 5 Stacks
y = new Stack(*x);
delete x;
delete [] z;
The copy constructor copies the contents of one object to another object. The two objects must be members of the same class.
string a; string c(a); // or string c = a;
As an example, suppose you have a string class:
class string {
public:
string(const string&);
protected:
char *str;
int length;
}
Then the copy constructor should look something like:
string::string(const string & s) {
length = s.length;
str = new char [ length + 1 ];
if ( str == 0 ) {
fprintf(stderr, "string::string: could not allocate a string of length %d\n",
length);
exit(1);
}
strcpy( str, s.str );
}
|
class string {
public:
string& operator=(const string &);
string& operator+=(const string&);
string& operator+=(const char*);
...
}
string& string::operator=(const string &s)
// don't do anything if the object to be copied is the same as
// the current object
if (*this != s) {
length = s.length;
delete [] str; // free the memory for the old string
str = new char [ length + 1 ]; // allocate memory for the new string
if ( str == 0 ) {
fprintf(stderr, "string::string: could not allocate a string of length %d\n",
length);
exit(1);
}
strcpy( str, s.str );
}
}
string& operator+=(const string& s) {
len += s.len;
char *p = new char[len+1];
assert( p != 0);
strcpy(p, str);
strcat(p, s.str);
delete [] str; // free up old memory!
str = p;
return *this;
}
string& operator+=(const char *s) {
len += strlen(s);
char *p = new char[len+1];
assert( p != 0);
strcpy(p, str);
strcat(p, s);
delete [] str; // free up old memory!
str = p;
return *this;
}
|