User Tools

Site Tools


haas:fall2024:common:cppclass1

Beginning Classes (and C++)

So far this semester we have been exclusively using the C Programming Language. C++ is in many ways an evolved C, taking and adding to its capabilities (and in some ways enabling some bad programming habits).

C++'s claim to fame is that it is “Object-Oriented”, which is based on this notion of classes, objects, and code management in general.

To know C is to know like 90% of C++. C++ merely adds a few things. If you do not know C, that means one must effectively learn two languages to get up and running in C++.

So, once again: EVERYTHING you have learned in C is pretty much valid C++ code.

For example, if we made a file called hello.cc (note the extension– the C++ compiler prefers we name our files with a .cc, .cpp, .c++, or .C extension to distinguish it from C's .c), we can pull of what should be a very familiar looking program:

#include <stdio.h>
 
int main()
{
    printf("Hello, World!\n");
    return(0);
}

That IS C code. It can be dropped wholesale into a C++ file and compiled with a C++ compiler (g++ in our case).

Classes (Implementation)

The centerpiece of C++ is its ability to use classes.

What you need to know about classes is that they are essentially structs with added capabilities. If you understand structs, you understand the foundation of classes.

Following is the declaration of a Rectangle Class (notice how similar it is to declaring a struct). It might not be a bad idea to put this in a file called rectangle.h:

class Rectangle {
    public:
        Rectangle();         // Constructor (parameterless)
        Rectangle(int, int); // Overloaded  (parametered)
        void setWidth(int);  // Accessor Method
        void setHeight(int); // Accessor Method
        int  getWidth();     // Accessor Method
        int  getHeight();    // Accessor Method
        int  area();         // Calculate the area of the Rectangle
        int  perimeter();    // Calculate the perimeter of the Rectangle
 
    private:
        int width;
        int height;
};

Now, a difference between a class and a struct is that classes can have function prototypes (structs do not allow this, although they CAN have function pointers).

We see the use of some labels- “Public:” and “Private:” (there is a third- “Protected:”, these three denote class access control). Labels themselves are not unique to C++; we can use them in C. But in C++, these three labels hold special meaning.

Basically:

  • Public class data (data denotes functions and variables) is accessible by all (what we're used to up to this point).
  • Protected class data is only accessible to what are called derived classes (child classes– we'll get to this).
  • Private class data is only accessible to the class itself.

Using these levels of access control, we can better manage our data and code by dictating how others can utilize our code. Again, this is really more of an organizational thing. Let me say it again, C++ is more about managing your C code. If you don't understand the C part, how can you be expected to successfully manage it?

Now for the class implementation. Some new syntax is used; put this in a file called rectangle.cc:

Rectangle :: Rectangle()
{
    width  = 0;
    height = 0;
}
 
Rectangle :: Rectangle(int width, int height)
{
    this.width  = width;
    this.height = height;
}
 
void Rectangle :: setWidth(int width)
{
    this.width  = width;
}
 
void Rectangle :: setHeight(int height)
{
    // Left as an exercise to the implementer
}
 
int Rectangle :: getWidth()
{
    // Left as an exercise to the implementer
}
 
int Rectangle :: getHeight()
{
    return(height);
}
 
int Rectangle :: area()
{
    // Left as an exercise to the implementer
}
 
int Rectangle :: perimeter()
{
    // Left as an exercise to the implementer
}

Immediately, five new things have been used in this code.

  • The presence of the class name to associate class scope of our code (perimeter() is not a general function– it is IN the Rectangle class. Therefore, the ONLY way to call it is through the Rectangle class, as part of a Rectangle class object).
  • The use of the class scoping operator (::) – perimeter() is a member of the Rectangle class. The :: helps to solidify this relationship.
  • The Constructor. This is an optional function we can create, which matches the class name. It automatically gets run upon class instantiation (ie making an instance of the class).
  • The this class pointer. “this” is a convenient way to refer to yourself- the Rectangle class has its own height and width member variables, and they are different from the parametered height and width variables we can send in (we didn't have to name the parameters the same, but this shows that if we do, we can avoid confusion by using “this”).
  • Function overloading– we can actually have multiple functions with the same name. The criteria is that some other aspect of its signature needs to vary (ie a different number of parameters).

Using classes

Now that we have a class, let's actually use it. Please note that Object-Oriented Programming has further solidified a certain role in the development process– with C we had library implementers, application implementers, and users. In C++, those same relationships exist, only they tend to become more pronounced (you aren't always implementing all the classes you use).

The following code will utilize our Rectangle class through instantiating a few objects (an object is a class in action). Put this in a file called main.cc. Not how similar it looks to C code:

#include <stdio.h>
#include "rectangle.h"
 
int main()
{
    Rectangle r1, r2, *r3;
 
    r3 = new Rectangle(14, 15);
 
    r1.setWidth(24);
    r1.setHeight(16);
 
    //r2.height = 17;
    //r2.width  = 13;
 
    printf("r1 has a width of %d and a height of %d.\n", r1.getWidth(), r1.getHeight);
    printf("r1's perimeter is %d and area is %d.\n", r1.perimeter(), r1.area);
 
    //printf("r1 has a width of %d and a height of %d.\n", r1.getWidth(), r1.getHeight);
    //printf("r1's perimeter is %d and area is %d.\n", r1.perimeter(), r1.area);
 
    // Do the same- display these values for r3
 
    return(0);
}

Compilation

To compile this code, we treat it as a multi-file program (no different than with C). Remember to use g++, it is the C++ compiler:

$ g++ -c rectangle.cc
$ g++ -c main.cc
$ g++ -o myprog main.o rectangle.o
haas/fall2024/common/cppclass1.txt · Last modified: 2013/03/29 16:19 by 127.0.0.1