Home Page
The Basics
Arrays
Classes
Abstract Data Types
Dynamic Memory Allocation
Operator Overloading
Lists
C++ Style Strings
Linked Lists
Stacks and Queues

Templates
Sorting
Variable types
Enumerated Data Type:
keyword: enum

an enumerated data type is that you are counting all the objects.  It is similar to a set.


Anonymous enumerated data type:
Example:
     enum {LIST_OK, LIST_NO_MEM,…..}

you don't need to specify numbers for the error codes.  That is done automatically.  The first one is automatically assigned the value of "0" and the next on "1" and so on.  (LIST_OK = 0, LIST_NO_MEMORY = 1, …)

Later on in the program:
int err;
.
.
err = LIST_OK;

enumerations can also be given names.
Named enumerated data type
Example:
enum ErrorCode {LIST_OK, LIST_NO_MEM, …};

This is a completely new data type.  Now you can create functions that return ErrorCode's

ErrorCode err = LIST_OK;

You can also choose your own values for enumerations:
Example:
enum set{A=8, B=10, C, D};

if a value is not set, the value takes up where you last specified a value.  For instance, in the example above, C=11 and D=12 because the last value you specified was for B.

Another interesting fact is that you can double-up values.
     enum set{A=-1, B, C, D=0};

B, by default is given the value "0" but you can still specify that D also has the value of "0".

How can this be useful to us in a specific way?  Think about the situation when you have a class named Date.



class Date
{
public:
     enum Month {Jan=1, Feb, Mar, Apr,… Dec};
     int day;
     Month month;     // must place after enum setting
     int year;
     set_date(Month, int, int);
};

Now, if someone wants to use these month symbols outside the class method, it would be done in the following manner:

Date d;

d.set_date(Date::Apr, 17, 2001);

With this information we can definitely get around the array size problem we had earlier where we declared a const int outside the class.

Example:  (recall the String class we created)
class String
{
     enum {max_size = 100};     // note that it is private
     char data[max_size];

public:
     func();
};

/**************************************************************/
String::func()
{
. . .
a = max_size;     // use just as expected
}

Note that the enumerated max_size is not an L-value and you cannot assign values to them

Ways of allocating memory:

automatic variables:
keyword: auto

automatic variables are declared but memory for those variables does not exist until that function is called.  When the function is called that contains them, the memory will be allocated.  This is why we can get away with recursion, because every time a function is called, it sets up a new copy of those variables
Example:
Standard implementation               Alternate Implementation
func()                                func()
{                                     {
     int a;                                auto int a;
     int *p;                               auto int *p;
}                                     }


global variables:
Global variables are variables you can have outside of a function.  They are available to everybody.
global variables are static variables.


local variables:
variables that are inside a function are called local variables and can only be used within the scope of the function.  They are dynamically created when the function is called.  The is a very subtle difference between this and the dynamic memory allocation when you call new or malloc.

static variables:
a static variable is a global variable which is set up at the beginning of a program.  They have no idea who is going to use them first.  They are called static because their allocation is not dynamically changed.



If you set g=0 in A.C you want to be able to print out and set g from within B.C  You want a global variable available to both A.C and B.C so that it can be shared back and forth.  The only problem is… Where is the memory for this?  When you compile and create object files for A and B, it says that there is a global variable in A.C and so it creates memory for it.  Likewise in B.C the compiler creates static memory for the variable.  So, both A.o and B.o have memory set aside for g. Which memory is correct??

As it turns out, both are correct.  This means that when we make changes to g in A and then do the same thing in B, B is going to access something entirely different.  How do we get around this problem?


Two keywords: are available in C and C++
extern -
static -

extern - keyword that you put in front of a variable declaration which tells the compiler there is a symbol of this type but the memory is somewhere else.

so in A.h declare g as:    extern int g;

now when A.C sees it and B.C sees it, they don't allocate memory automatically.  

**Note that you must have memory declared in one and only one of the source files also.
You would think that this would be a compiler error because you are declaring the variable in both the A.h and the A.C file but in this special case it is not.
static - when applied to a global variable means
that this symbol can only be seen inside this source
code file.  is also useful when you want a variable inside a
function to preserve it's value between the times
it gets called and in the function is the only place
that you are going to use it.  All variables in a function
are destroyed when you leave the function.  BUT if you
declare the variables inside the function as static, they
be used just like any other variable with the exception

that the memory associated with that function is in the static memory space.  In other words, the memory that is initialized when the program is started and not when the function is called.  It's like a global variable but that symbol is valid only within that function. It will only be initialized once.

if you want a function such as e( ) to be made unseen by any other function including source code that has included the M.h file, you need to make it a static function.

Example of the use of static:
say that you have a function called f( );

f()
{
     int a;
     static int b;
     .
     .
}

memory associated with the function symbol is valid only in the function.
initializing it here (b=0) will initialize it only once.  How does this effect us with classes?

Example:
class W
{
     static int a;     // takes this member and allocates it out of static
                              // memory before the program is started
};

This will allocate static memory before the program runs.  You may wonder how it does this if you don't know how many instances of the variable you will have.  The answer is you don't .  This member has only one instance of that member made for the class.

Note that there is only one instance of 'a' for the entire class.  All instances of the class have the same 'a' in common.  Whenever anyone accesses that member 'a' they will get the same value as anyone else who accesses it.

But there is a problem. You can't initialize it within a class so how do you initialize it?  

If you declare a static data member of a class, you need to allocate memory for it.  Before the constructor and the destructor in your source code file:

     static int W::a = 0; // allocates memory and initializes

If you are dealing with constants you can declare it as follows:
class W
{
     static const int SIZE = 50;
     int ar[SIZE];
     …
};

Note: this is the ONLY time you can initialize
a member within a class. ( if it is a static const)

You can initialize within a class if you declare it as a const int.  The SIZE will then remain in the class.  This declares a constant variable without having be a global constant.  This is a better way than using enumeration for declaring constants.

static says that nobody outside this source code file knows about this instance of the variable.


Sample code for this section to be posted on the official course site under test13.C and test13a.C
You can't have a const int in a class because it will be initialized for every instance in class.  You can't do this.  But if you declare it as static… for example:

static const int SIZE = 50;

then it allows you to have the constant variable declared within the class without being a global const int.  If you code:

static int a:          // need to declare to make memory
static const int a;     created here
.
.
enum {SIZE = 50};

Key Note:  
Memory for static variables is created when program is run not when function is called
Static variables don't go away when you leave the function.