Practical C++ Programming
Authors: Oualline S.
Published year: 2003
Pages: 152-153/364
Buy this book on amazon.com >>
I l @ ve RuBoard

14.2 Constant Functions

C++ lets you define two types of numbers : constant and nonconstant. For example:

int index;                // Current index into the data array
const int DATA_MAX(100);  // Maximum number of items in the array

These two items are treated differently. For example, you can change the value of index , but you can't change DATA_MAX .

Now let's consider a class to implement a set of numbers from 0 to 31. The definition of this class is:

// Warning: The member functions in this class are incomplete
//          See below for a better definition of this class
class int_set {
    private:
        // ... whatever
    public:
        int_set(  );                       // Default constructor
        int_set(const int_set& old_set); // Copy constructor
        void set(int value);             // Set a value
        void clear(int value);           // Clear an element
        int test(int value);             // See whether an element is set
};

As with numbers, C++ will let you define two types of int_set objects: constant and nonconstant:

int_set var_set;      // A variable set (we can change this)

var_set.set(1);       // Set an element in the set

// Define a constant version of the set (we cannot change this)
const int_set const_set(var_set);

In the int_set class, there are member functions such as set and clear that change the value of the set. There is also a function test that changes nothing.

Obviously you don't want to allow set and clear to be used on a constant. However, it is okay to use the test member function.

But how does C++ know what can be used on a constant and what can't? The trick is to put the keyword const at the end of the function header. This tells C++ that this member function can be used for a constant variable. So if you put const after the member function test , C++ will allow it to be used in a constant. The member functions set and clear do not have this keyword, so they can't be used in a constant.

class int_set {
    private:
        // ... whatever
    public:
        int_set(  );             // Default constructor
        int_set(const int_set& old_set); // Copy constructor
        void set(int value);   // Set a value
        void clear(int value); // Clear an element
        int test(int value) const;   // See whether an element is set
};

Thus, in your code you can do the following:

int_set var_set;      // A variable set (we can change this)

var_set.set(1);       // Set an element in the set (legal)

// Define a constant version of the set (we cannot change this)
const int_set const_set(var_set);

// In the next statement we use the member function "test" legally
std::cout << "Testing element 1. Value=" << const_set.test(  ) << '\n';

However, you cannot do the following:

const_set.set(5);    // Illegal (set is not allowed on a const)

The member function set was not declared const , so it cannot be invoked on a const int_set object.

I l @ ve RuBoard
I l @ ve RuBoard

14.3 Constant Members

Classes may contain constant members. The problem is that constants behave a little differently inside classes than outside. Outside, a constant variable declaration must be initialized . For example:

const int data_size = 1024;	 // Number of data items in the input stream

Inside a class, constants are not initialized when they are declared. For example:

class data_list {
    public:
        const int data_size;   // Number of items in the list
    // ... rest of the class
};

Constant member variables are initialized by the constructor. However, it's not as simple as this:

class data_list {
    public:
        const int data_size;   // Number of items in the list

        data_list(  ) {
            data_size = 1024;   // This code won't work
        };
    // ... rest of the class
};

Instead, because data_size is a constant, it must be initialized with a special syntax:

data_list(  ) : data_size(1024) {
        };

But what happens if you want just a simple constant inside your class? Unfortunately C++ doesn't allow you to do the following:

class foo {
    public: 
        const int foo_size = 100;  // Illegal

You are left with two choices:

  • Put the constant outside the code:

    const int foo_size = 100;	    // Number of data items in the list
    
    class foo {
    

    This makes foo_size available to all the world.

  • Use a syntax trick to fool C++ into defining a constant:

    class foo {
        public:
            enum {foo_size = 100};  // Number of data items in the list
    

    This defines foo_size as a constant whose value is 100 . It does this by actually declaring foo_size as a element of an enum type and giving it the explicit value 100 . Because C++ treats enums as integers, this works for defining integer constants.

    The drawbacks to this method are that it's tricky, it works only for integers, and it exploits some holes in the C++ syntax that may go away as the language is better defined. Such code can easily cause difficulties for other programmers trying to maintain your code who aren't familiar with the trick.

I l @ ve RuBoard
Practical C++ Programming
Authors: Oualline S.
Published year: 2003
Pages: 152-153/364
Buy this book on amazon.com >>

Similar books on Amazon