struct

Classes vs Stacks in C++

The class and the stack are similar in some aspects.

It is easy to implement a data structure in C++. If we want to create an object that has no member functions, just data, a struct is more than sufficient. A class that has no members other than the default constructor and destructor would be similar in layout and “feel” to a struct.

#include <iostream>

using namespace std;

int main(void){

    struct SData{
        int iValue;
        double dValue;
        string strValue;
    };

    class CData{
        int iValue;
        double dValue;
        string strValue;
    };

    return 0;

}

The key difference then between a struct and a class without any member functions is data hiding – a class’s member variables are by default set to private.  This hides the value from functions outside the class – a big plus plus.

As an example, let’s compare an implementation of a stack using structs with an implementation using classes.

A stack is a data structure that accepts data using a push operation, and removes data using a pop operation. Data is stored in a last in, first out order, abbreviated LIFO. It’s similar to a stack of plates, or, unfortunately, the emails in my inbox.

Suppose we have a stack that stores numbers. The stack starts out empty, and we push 9, 14, and 27 onto the stack using three push operations. When we execute a pop operation, the number we get is 27, the last number pushed onto the stack.

First, let’s design a simple stack using an array to store the data and a structure to store the array. We will then need a function to push an item onto the stack, a function to pop an item off of the stack, and a function to initialize the stack.

#include <iostream>

using namespace std;

const int Stack_Size = 100;

struct stack{
    int iCount;
    int iaData[Stack_Size];
};


int stackPop(struct stack &theStack);
void stackPush(struct stack &theStack, int iValue);
void stackInit(struct stack &theStack);

int main(void){

    struct stack exmpStack;

    stackInit(exmpStack);

    //push some values on
    stackPush(exmpStack, 533);
    stackPush(exmpStack, 97);
    stackPush(exmpStack, 66);
    stackPush(exmpStack, 62);

    cout << "Item on top of the stack is " << stackPop(exmpStack) << endl;
    cout << "Next item is " << stackPop(exmpStack) << endl;    


    return 0;
}

//remove an item and return it to
//the calling function
int stackPop(struct stack &theStack){
    //one item less in the stack
    theStack.iCount--;
    //we can use that number
    //since arrays are indexed starting at 0
    return theStack.iaData[theStack.iCount];
} //end stackPush()

//add an item
void stackPush(struct stack &theStack, int iValue){
    theStack.iaData[theStack.iCount] = iValue;
    theStack.iCount++;
} //end stackPop()

//initilize the structure
void stackInit(struct stack &theStack){
    theStack.iCount = 0;
}

The problem is that the stack and its related functions are defined separately, forcing us to pass the struct variable into each method. The structure’s fields are also available to anyone. We could easily corrupt the stack.

All right, now let’s see how the class implementation goes.

A class definition begins with the keyword class. We will declare two class variables, and set them to private by using the keyword private followed by a semicolon to indicate that the variables that follow are private. The keyword private defines the variables as being inaccessible to non-member functions. We will make set the class’s member functions to public using the keyword public followed by as semicolon.

All functions that are members of the class must be defined with the class name followed by two semicolons in front of the function name. The two semicolons are what is known as a scope operator.

#include <iostream>

using namespace std;

const int Stack_Size = 100;

class CStack{
    //private class variables
    //only accessible through the
    //class functions
    private:
        int iCount;
        int iData[Stack_Size];
    //class functions are declared public
    //only way to access the values stored
    //on the stack
    public:
        void init(void);
        void push(const int iParam);
        int pop();

};


int main(void){

    CStack theStack;
    theStack.init();

    theStack.push(47);
    theStack.push(711);
    theStack.push(73);


    cout << theStack.pop() << endl;
    cout << theStack.pop() << endl;
    cout << theStack.pop() << endl;

    return 0;
}


void CStack::init(){
    iCount=0;
}

void CStack::push(const int iParam){
    iData[iCount] = iParam;
    iCount++;
}

int CStack::pop(){
    return iData[--iCount];
}

As we can see, using a class is much like using a structure. Declaring the class variable is the same, except of course we use the keyword class instead of the keyword struct. Accessing the class members is the same as well; it’s done using the dot operator. The difference is that we can only access the class members that are set to public, and the class members may be either functions or variables.

The one annoyance with the stack class we have defined is that we have to explicitly initialize it. It would be better if we just used a constructor, which is automatically called when an instance of the class is created. The constructor function has the same name as the class. Like other functions, the class constructor can accept arguments.

#include <iostream>

using namespace std;

class CPerson{
    private:
        string strName;
        int iAge;
    public:
        CPerson(string strNameParam, int iAgeParam);
        void PrintData();

};

int main(void){

    class CPerson joe("Jospeh Johnson", 32);
    joe.PrintData();

    return 0;
}

CPerson::CPerson(string strNameParam, int iAgeParam){
    strName = strNameParam;
    iAge = iAgeParam;
}

void CPerson::PrintData(){
    cout << "Name: " << strName << endl;
    cout << "Age: " << iAge << endl;
}

Note well that the class constructor is automatically called when the variable is created.