Home Programming Demystified Object-Oriented Programming with C++

Demystified Object-Oriented Programming with C++

By Dorothy R. Kirk
books-svg-icon Book
Subscription
$10 p/m for first 3 months. $15.99 p/m after that. Cancel Anytime!
What do you get with a Packt Subscription?
This book & 7000+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with a Packt Subscription?
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with eBook + Subscription?
Download this book in EPUB and PDF formats, plus a monthly download credit
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with a Packt Subscription?
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with eBook?
Download this book in EPUB and PDF formats
Access this title in our online reader
DRM FREE - Read whenever, wherever and however you want
Online reader with customised display settings for better reading experience
What do you get with video?
Download this video in MP4 format
Access this title in our online reader
DRM FREE - Watch whenever, wherever and however you want
Online reader with customised display settings for better learning experience
What do you get with video?
Stream this video
Access this title in our online reader
DRM FREE - Watch whenever, wherever and however you want
Online reader with customised display settings for better learning experience
What do you get with Audiobook?
Download a zip folder consisting of audio files (in MP3 Format) along with supplementary PDF
What do you get with Exam Trainer?
Flashcards, Mock exams, Exam Tips, Practice Questions
Access these resources with our interactive certification platform
Mobile compatible-Practice whenever, wherever, however you want
BUY NOW $10 p/m for first 3 months. $15.99 p/m after that. Cancel Anytime!
Subscription
What do you get with a Packt Subscription?
This book & 7000+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with a Packt Subscription?
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with eBook + Subscription?
Download this book in EPUB and PDF formats, plus a monthly download credit
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with a Packt Subscription?
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with eBook?
Download this book in EPUB and PDF formats
Access this title in our online reader
DRM FREE - Read whenever, wherever and however you want
Online reader with customised display settings for better reading experience
What do you get with video?
Download this video in MP4 format
Access this title in our online reader
DRM FREE - Watch whenever, wherever and however you want
Online reader with customised display settings for better learning experience
What do you get with video?
Stream this video
Access this title in our online reader
DRM FREE - Watch whenever, wherever and however you want
Online reader with customised display settings for better learning experience
What do you get with Audiobook?
Download a zip folder consisting of audio files (in MP3 Format) along with supplementary PDF
What do you get with Exam Trainer?
Flashcards, Mock exams, Exam Tips, Practice Questions
Access these resources with our interactive certification platform
Mobile compatible-Practice whenever, wherever, however you want
  1. Free Chapter
    Chapter 1: Understanding Basic C++ Assumptions
About this book

While object-oriented software design helps you write more easily maintainable code, companies choose C++ as an OO language for its speed. Object-oriented programming (OOP) in C++ is not automatic – understanding OO concepts and how they map to C++ language features as well as OOP techniques is crucial. You must also know how to distinguish your code by utilizing well-tested, creative solutions, which can be found in popular design patterns. This book will help you to harness OOP in C++ for writing better code.

Starting with the essential C++ features that serve as building blocks for the main chapters, this book explains fundamental object-oriented concepts and shows you how to implement them in C++. With the help of practical code examples and diagrams, you’ll find out how and why things work. The book’s coverage furthers your C++ repertoire by including templates, exceptions, operator overloading, STL, and OO component testing. You’ll also discover popular design patterns with in-depth examples and how to use them as effective programming solutions to recurring OOP problems.

By the end of this book, you’ll be able to employ essential and advanced OOP concepts confidently to create enduring and robust software.

Publication date:
March 2021
Publisher
Packt
Pages
568
ISBN
9781839218835

 

Chapter 1: Understanding Basic C++ Assumptions

This chapter will briefly identify the basic language syntax, constructs, and features of C++, which you are assumed to have familiarity with from either the basic syntax of C++, C, Java, or similar languages. These core language features will be reviewed concisely. If these basic syntax skills are not familiar to you after completing this chapter, please first take the time to explore a more basic syntax-driven C++ text before continuing with this book. The goal of this chapter is not to teach each of the assumed skills in detail, but to briefly provide a synopsis of each basic language feature to allow you to quickly recall a skill that should already be in your programming repertoire.

In this chapter, we will cover the following main topics:

  • Basic language syntax
  • Basic I/O
  • Control structures, statements, and looping
  • Operators
  • Function basics
  • User defined type basics
  • Namespace basics

By the end of this chapter, you'll have a succinct review of the very basic C++ language skills in which you're assumed to be proficient. These skills will be necessary in order to move forward with the next chapter successfully. Because most of these features do not utilize OO features of C++, I will refrain from using OO terminology (as much as possible) and will instead introduce appropriate OO terminology when we move into the OO sections of this book.

 

Technical requirements

Please ensure that you have a current C++ compiler available; you'll want to try many of the online code examples. Minimally, please download g++ from https://gcc.gnu.org.

Online code for full program examples can be found at the following GitHub URL: https://github.com/PacktPublishing/Demystified-Object-Oriented-Programming-with-CPP/blob/master/Chapter01. Each full program example can be found in the GitHub repository under the appropriate chapter heading (subdirectory) in a file that corresponds to the chapter number, followed by a dash, followed by the example number in the chapter at hand. For example, the first full program in this chapter can be found in the subdirectory Chapter01 in a file named Chp1-Ex1.cpp under the aforementioned GitHub directory.

The CiA video for this chapter can be viewed at: https://bit.ly/3c6oQdK.

 

Reviewing basic C++ language syntax

In this section, we will briefly review basic C++ syntax. We'll assume that you are either a C++ programmer with non-OO programming skills, or that you've programmed in C, Java, or a similar strongly typed checked language with related syntax. You may also be a long-standing professional programmer who is able to pick up another language's basics quickly. Let's begin our brief review.

Variable declarations and standard data types

Variables may be any length and may consist of letters, digits, and underscores. Variables are case-sensitive and must begin with a letter or an underscore. Standard data types in C++ include:

  • int: To store whole numbers
  • float: To store floating-point values
  • double: To store double-precision floating-point values
  • char: To store a single character
  • bool: For Boolean values of true or false

Here are a few straightforward examples using the standard data types described above:

int x = 5;
int a = x;
float y = 9.87; 
float y2 = 10.76f;  // optional 'f' suffix on float literal
float b = y;
double yy = 123456.78;
double c = yy;
char z = 'Z';
char d = z;
bool test = true;
bool e = test;
bool f = !test;

Reviewing the previous fragment of code, note that a variable can be assigned a literal value, such as int x = 5;, or that a variable may be assigned the value or contents of another variable, such as int a = x;. These examples illustrate this ability with various standard data types. Note that for the bool type, the value can be set to true or false, or to the opposite of one of those values using ! (not).

Variables and array basics

Arrays can be declared of any data type. The array name represents the starting address of the contiguous memory associated with the array's contents. Arrays are zero-based in C++, meaning they are indexed starting with array element[0] rather than array element[1]. Most importantly, range checking is not performed on arrays in C++; if you access an element outside the size of an array, you are accessing memory belonging to another variable and your code will likely fault very soon.

Let's review some simple array declarations, an initialization, and an assignment:

char name[10] = "Dorothy"; 
float grades[20];  
grades[0] = 4.0;

Above, notice that the first array, name, contains 10 char elements, which are initialized to the seven characters in the string literal "Dorothy", followed by the null character ('\0'). The array currently has two unused elements at the end. The elements in the array can be accessed individually using name[0] through name[9], as arrays in C++ are zero-based. Similarly, the array above, which is identified by the variable grades, has 20 elements, none of which are initialized. Any array value accessed prior to initialization or assignment can contain any value; this is true for any uninitialized variable. Notice that just after the array grades is declared, its zeroth element is assigned a value of 4.0.

Arrays of characters are often conceptualized as strings. Many standard string functions exist in libraries such as <cstring>. Arrays of characters should be null-terminated if they are to be treated as strings. When arrays of characters are initialized with a string of characters, the null character is added automatically. However, if characters are added one by one to the array via assignment, it would then be the programmer's job to add the null character ('\0') as the final element in the array. Let's see some basic examples:

char book1[20] = "C++ Programming":
char book2[25];
strcpy(book2, "OO Programming with C++");
strcmp(book1, book2);
length = strlen(book2);

Above, the first variable book1 is declared to be 20 characters in length and is initialized to a string literal of "C++ Programming". Next, variable book2 is declared to be an array of 25 characters in length but is not initialized with a value. Next, the function strcpy() from <cstring> is used to copy the string literal "OO Programming with C++" into the variable book2. Note that strcpy() will automatically add the null terminating character to the destination string. On the next line, strcmp(), also from <cstring>, is used to lexicographically compare the contents of variables book1 and book2. This function returns an integer value, which can be captured in another variable or used in a comparison. Lastly, the function strlen() is used to count the number of characters in book2 (excluding the null character).

Comment styles

Two styles of comments are available in C++:

  • The /* */ style provides comments spanning multiple lines of code. This style may not be nested with other comments of this same style.
  • The // style of comment provides a simple comment to the end of the current line.

Using the two comment styles together can allow nested comments, which can be useful when debugging code.

Now that we have successfully reviewed basic C++ language features such as variable declarations, standard data types, array basics, and comment styles, let's move forward to recap another fundamental language feature of C++: basic keyboard input and output using the <iostream> library.

 

Recapping basic I/O

In this section, we'll briefly review simple character-based input and output with the keyboard and monitor. Simple manipulators will also be reviewed to both explain the underlying mechanics of I/O buffers and to provide basic enhancements and formatting.

The iostream library

One of the easiest mechanisms for input and output in C++ is the use of the <iostream> library. The header file <iostream> contains definitions of the data types istream and ostream. Instances of these data types, cin, cout, and cerr, are incorporated by including the std namespace. The <iostream> library facilitates simple I/O:

  • cin can be used in conjunction with the extraction operator >> for input
  • cout can be used in conjunction with the insertion operator << for output
  • cerr can also be used in conjunction with the insertion operator, but for errors

Let's review an example showcasing simple I/O:

#include <iostream>
using namespace std;
int main()
{
    char name[20];
    int age;
    cout << "Please enter a name and an age: ";
    cin >> name >> age;
    cout << "Hello " << name;
    cout << ". You are " << age << " years old." << endl;
    return 0;
}

First, we include the <iostream> library and indicate that we're using the std namespace to gain usage of cin and cout (more on namespaces later in this chapter). Next, we introduced the main() function, which is the entry point in our application. Here we declare two variables, name and age, neither of which is initialized. Next, we prompt the user for input by placing the string "Please enter a name and an age: " in the buffer associated with cout. When the buffer associated with cout is flushed, the user will see this prompt on the screen.

The keyboard input string is then placed in the buffer associated with cout using the extraction operator <<. Conveniently, one mechanism that automatically flushes the buffer associated with cout is the use of cin to read keyboard input into variables, such as on the next line where we read the user input into the variables, name and age, respectively.

Next, we print out a greeting of "Hello" to the user, followed by the name entered, followed by an indication of their age, gathered from the second piece of user input. The endl at the end of this line both places a newline character '\n' into the output buffer and ensures that the output buffer is flushed – more of that next. The return 0; declaration simply returns a program exit status to the programming shell, in this case, the value 0. Notice that the main() function indicates an int for a return value to ensure this is possible.

Basic iostream manipulators

Often, it is desirable to be able to manipulate the contents of the buffers associated with cin, cout, and cerr. Manipulators allow the internal state of these objects to be modified, which affects how their associated buffers are formatted and manipulated. Manipulators are defined in the <iomanip> header file. Common manipulator examples include:

  • endl: Places a newline character in the buffer associated with cout then flushes the buffer
  • flush: Clears the contents of the output stream
  • setprecision(int): Sets floating-point precision
  • setw(int): Sets width for input and output
  • ws: Removes whitespace characters from the buffer

Let's see a simple example:

#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
    char name[20];
    float gpa;   // grade point average
    cout << "Please enter a name and a gpa: "; 
    cin >> setw(20) >> name >> gpa;
    cout << "Hello " << name << flush;
    cout << ". GPA is: " << setprecision(3) << gpa << endl;
    return 0;
}

In this example, first notice the inclusion of the <iomanip> header file. Also, notice that setw(20) is used to ensure that we do not overflow the name variable, which is only 20 characters long; setw() will automatically deduct one from the size provided to ensure there is room for the null character. Notice that flush is used on the second output line – it's not necessary here to flush the output buffer; this manipulator merely demonstrates how a flush may be applied. On the last output line with cout, notice that setprecision(3) is used to print the floating-point gpa. Three points of precision account for the decimal point plus two places to the right of the decimal.

Now that we have reviewed simple input and output using the <iostream> library, let's move forward by briefly reviewing control structures, statements, and looping constructs.

 

Revisiting control structures, statements, and looping

C++ has a variety of control structures and looping constructs, which allow for non-sequential program flow. Each can be coupled with simple or compound statements. Simple statements end with a semicolon; more compound statements are enclosed in a block of code using a pair of brackets {}. In this section, we will be revisiting various types of control structures (if , else if, and else), and looping constructs (while, do while, and for) to recap simple methods for non-sequential program flow within our code.

Control structures: if, else if, and else

Conditional statements using if, else if, and else can be used with simple statements or a block of statements. Note that an if clause can be used without a following else if or else clause. Actually, else if is really a condensed version of an else clause with a nested if clause inside of it. Practically speaking, developers flatten the nested use into else if format for readability and to save excess indenting. Let's see an example:

#include <iostream>
using namespace std;
int main()
{
    int x;
    cout << "Enter an integer: ";
    cin >> x;
    if (x == 0) 
        cout << "x is 0" << endl;
    else if (x < 0)
        cout << "x is negative" << endl;
    else
    {
        cout << "x is positive";
        cout << "and ten times x is: " << x * 10 << endl;
    }  
    return 0;
}

Notice that in the else clause above, multiple statements are bundled into a block of code, whereas in the if and else if conditions only a single statement follows each condition. As a side note, in C++ any non-zero value is considered to be true. So, for example, testing if (x) would imply that x is not equal to zero – it would not be necessary to write if (x !=0), except possibly for readability.

Looping constructs: while, do while, and for loops

C++ has several looping constructs. Let's take a moment to review a brief example for each style, starting with the while and do while loop constructs.

#include <iostream>
using namespace std;
int main()
{
    int i = 0;
    while (i < 10)
    {
        cout << i << endl;
        i++;
    }
    i = 0;
    do 
    {
        cout << i << endl;
        i++;
    } while (i < 10);
    return 0;
}

With the while loop, the condition to enter the loop must evaluate to true prior to each entry of the loop body. However, with the do while loop, the first entry to the loop body is guaranteed – the condition is then evaluated before another iteration through the loop body. In the example above, both the while and do while loops are executed 10 times, each printing values 0-9 for variable i.

Next, let's review a typical for loop. The for loop has three parts within the (). First, there is a statement that is executed exactly once and is often used to initialize a loop control variable. Next, separated on both sides by semicolons in the center of the () is an expression. This expression is evaluated each time before entering the body of the loop. The body of the loop is only entered if this expression evaluates to true. Lastly, the third part within the () is a second statement. This statement is executed immediately after executing the body of the loop and is often used to modify a loop control variable. Following this second statement, the center expression is re-evaluated. Here is an example:

#include <iostream>
using namespace std;
int main()
{
    int i;
    for (i = 0; i < 10; i++) 
        cout << i << endl;
    for (int j = 0; j < 10; j++)
        cout << j << endl;
    return 0;
}

Above, we have two for loops. Prior to the first loop, variable i is declared. Variable i is then initialized with a value of 0 in statement 1 between the loop parentheses (). The loop condition is tested, and if true, the loop body is then entered and executed, followed by statement 2 being executed prior to the loop condition being retested. This loop is executed 10 times for i values 0 through 9. The second for loop is similar, with the only difference being variable j is both declared and initialized within statement 1 of the loop construct. Note that variable j only has scope for the for loop itself, whereas variable i has the scope of the entire block in which it is declared, from its declaration point forward.

Let's quickly see an example using nested loops. The looping constructs can be of any type, but below we'll review nested for loops.

#include <iostream>
using namespace std;
int main()
{
    for (int i = 0; i < 10; i++) 
    {
        cout << i << endl;
        for (int j = 0; j < 10; j++)
            cout << j << endl;
        cout << "\n";
    }
    return 0;
}

Above, the outer loop will execute 10 times with i values of 0 through 9. For each value of i, the inner loop will execute 10 times, with j values of 0 through 9. Remember, with for loops, the loop control variable is automatically incremented with the i++ or j++ within the loop construct. Had a while loop been used, the programmer would need to remember to increment the loop control variable in the last line of the body of each such loop.

Now that we have reviewed control structures, statements, and looping constructs in C++, we can move onward by briefly recalling C++'s operators.

 

Reviewing C++ operators

Unary, binary, and ternary operators exist in C++. C++ allows operators to have different meanings based on the context of usage. C++ also allows programmers to redefine the meaning of selected operators when used in the context of at least one user-defined type. The operators are listed below as a concise list. We'll see examples of these operators throughout the remainder of this section and throughout the course. Here is a synopsis of the binary, unary, and ternary operators in C++:

Table 1.1 – Binary Operators

Table 1.1 – Binary Operators

In the aforementioned binary operator list, notice how many of the operators have "shortcut" versions when paired with the assignment operator =. For example, a = a * b can be written equivalently using a shortcut operator a *= b. Let's take a look at an example that incorporates an assortment of operators, including usage of a shortcut operator:

score += 5;
score++;
if (score == 100)
    cout << "You have a perfect score!" << endl;
else
    cout << "Your score is: " << score << endl;
// equivalent to if - else above, but using ?: operator
(score == 100)? cout << "You have a perfect score" << endl :
                cout << "Your score is: " << score << endl; 

In the previous code fragment, notice the use of the shortcut operator +=. Here, the statement score += 5; is equivalent to score = score + 5;. Next, the unary increment operator ++ is used to increment score by 1. Then we see the equality operator == to compare the score with a value of 100. Finally, we see an example of the ternary operator ?: to replace a simple if-else statement. It is instructive to note that ?: is not preferred by some programmers, yet it is always interesting to review an example of its use.

Now that we have very briefly recapped the operators in C++, let's revisit function basics.

 

Revisiting function basics

A function identifier must begin with a letter or underscore and may also contain digits. The function's return type, argument list, and return value are optional. The basic form of a C++ function is as follows:

<return type> functionName (<argumentType argument1, …>)
{
    expression 1…N;
    <return value/expression;>
}

Let's review a simple function:

#include <iostream>
using namespace std;
int minimum(int a, int b)
{
    if (a < b)
        return a;
    else
        return b;
}
int main()
{
    int x, y;
    cout << "Enter two integers: ";
    cin >> x >> y;
    cout << "The minimum is: " << minimum(x, y) << endl;
    return 0;
}

In the simple example above, first, a minimum() function is defined. It has a return type of int and it takes two integer arguments: formal parameters a and b. In the main() function, minimum() is called with actual parameters x and y. The call to minimum() is permitted within the cout statement because minimum() returns an integer value; this value is passed along to the extraction operator (<<) in conjunction with printing. In fact, the string "The minimum is: " is first placed into the buffer associated with cout, followed by the return value from calling function minimum(). The output buffer is then flushed by endl (which first places a newline character in the buffer before flushing).

Notice that the function is first defined in the file and then called later in the file in the main() function. Strong type checking is performed on the call to the function by comparing the parameter types and their usage in the call to the function's definition. What happens, however, when the function call precedes its definition? Or if the call to the function is in a separate file from its definition?

In these cases, the default action is for the compiler to assume a certain signature to the function, such as an integer return type and that the formal parameters will match the types of arguments in the function call. Often, the default assumptions are incorrect; when the compiler then encounters the function definition later in the file (or when another file is linked in), an error will be raised indicating that the function call and definition do not match.

These issues have historically been solved with a forward declaration of a function included at the top of a file where the function will be called. Forward declarations consist of a function return type, function name and types, and the number of parameters. In C++, a forward declaration has been improved upon and is instead known as a function prototype. Since there are many interesting details surrounding function prototyping, this topic will be covered in reasonable detail in the next chapter.

As we move to the object-oriented sections in this book (Chapter 5, Exploring Classes in Detail, and beyond), we will learn that there are many more details and quite interesting features relating to functions. Nonetheless, we have sufficiently recalled the basics needed to move forward. Next, let's continue our C++ language review with user-defined types.

 

Reviewing user-defined type basics

C++ offers several mechanisms to create user-defined types. Bundling together like characteristics into one data type (later, we'll also add relevant behaviors) will form the basis for an object-oriented concept known as encapsulation in a later section of this text. For now, let's review the basic mechanisms to bundle together only data in struct, class, and typedef (to a lesser extent). We will also review enumerated types to represent lists of integers more meaningfully.

struct

A C++ structure in its simplest form can be used to collect common data elements together in a single unit. Variables may then be declared of the composite data type. The dot operator is used to access specific members of each structure variable. Here is a structure used in the most simple fashion:

#include <iostream>
#include <cstring>
using namespace std;
struct student
{
    char name[20];
    float semesterGrades[5];
    float gpa;
};
int main()
{
    student s1;
    strcpy(s1.name, "George Katz");
    s1.semesterGrades[0] = 3.0;
    s1.semesterGrades[1] = 4.0;
    s1.gpa = 3.5;
    cout << s1.name << " has GPA: " << s1.gpa << endl;
    return 0;
}

Stylistically, type names are typically in lower case when using structs. In the example above, we declare the user-defined type student using struct. The type student has three fields or data members: name, semesterGrades, and gpa. In the main() function, a variable s1 of type student is declared; the dot operator is used to access each of the variable's data members. Since structs are typically not used for OO programming in C++, we're not going to yet introduce significant OO terminology relating to their use. It's worthy of note that in C++, the tag student also becomes the type name (unlike in C where a variable declaration would need the word struct to precede the type).

typedef

A typedef can be used to provide a more mnemonic representation for data types. In C++, the relative need for a typedef has been eliminated in usage with a struct. Historically, a typedef in C allowed the bundling together of the keyword struct and the structure tag to create a user-defined type. However, in C++, as the structure tag automatically becomes the type, a typedef then becomes wholly unnecessary for a struct. Typedefs can still be used with standard types for enhanced readability in code, but in this fashion, the typedef is not being used to bundle together like data elements, such as with a struct. Let's take a look at a simple typedef:

typedef float dollars; 

In the previous declaration, the new type dollars can be used interchangeably with the type float. It is not productive to demonstrate the archaic use of typedef with a structure, so let's move on to the most used user-defined type in C++, the class.

class

A class in its simplest form can be used nearly like a struct to bundle together related data into a single data type. In Chapter 5, Exploring Classes in Detail, we'll see that a class is typically also used to bundle related functions together with the new data type. Grouping together data and behaviors relevant to that data is the basis of encapsulation. For now, let's see a class in its simplest form, much like a struct:

#include <iostream>
#include <cstring>
using namespace std;
class Student
{
public:
    char name[20];
    float semesterGrades[5];
    float gpa;
};
int main()
{
    Student s1;
    strcpy(s1.name, "George Katz");
    s1.semesterGrades[0] = 3.0;
    s1.semesterGrades[1] = 4.0;
    s1.gpa = 3.5;
    cout << s1.name << " has GPA: " << s1.gpa << endl;
    return 0;
}

Notice above that the code is very similar to that used in the struct example. The main difference is the keyword class instead of the keyword struct and the addition of the access label public: at the beginning of the class definition (more on that in Chapter 5, Exploring Classes in Detail). Stylistically, the capitalization of the first letter in the data type, such as Student, is typical for classes. We'll see that classes have a wealth of features and are the building blocks for OO programming. We'll introduce new terminology such as instance, to be used rather than variable. However, this section is only a review of skills assumed, so we'll need to wait to get to the exciting OO features of the language. Spoiler alert: all the wonderful things classes will be able to do also apply to structs; however, we'll see that structs stylistically won't be used to exemplify OO programming.

enum

Enumerated types may be used to mnemonically represent lists of integers. Unless otherwise initialized, integer values in the enumeration begin with zero and increase by one throughout the list. Two enumerated types may not utilize the same enumerator names. Let's now see an example:

#include <iostream>
using namespace std;
enum day {Sunday,  Monday, Tuesday, Wednesday, Thursday,
          Friday, Saturday};
enum workDay {Mon = 1, Tues, Wed, Thurs, Fri};
int main()
{
    day birthday = Monday;
    workDay payday = Fri;
    cout << "Birthday is " << birthday << endl;
    cout << "Payday is " << payday << endl;
    return 0;
}

In the previous example the enumerated type day has values of 0 through 6, starting with Sunday. The enumerated type workDay has values of 1 through 5, starting with Mon. Notice the explicit use of Mon = 1 as the first item in the enumerated type has been used to override the default starting value of 0. Interestingly, we may not repeat enumerators between two enumerated types. For that reason, you will notice that Mon is used as an enumerator in workDay because Monday has already been used in enumerated type day. Now, when we create variables such as birthday or payday, we can use meaningful enumerated types to initialize or assign values, such as Monday or Fri. As meaningful as the enumerators may be within the code, please note that the values when manipulated or printed will be their corresponding integer values.

Now that we have revisited simple user-defined types in C++, including struct, typedef, class, and enum, we are ready to move onward to reviewing our next language necessity, the namespace.

 

Recapping namespace basics

The namespace utility was added to C++ to add a scoping level beyond the global scope to applications. This feature can be used to allow two or more libraries to be utilized without concern that they may contain duplicative data types, functions, or identifiers. The programmer needs to activate the desired namespace in each relevant portion of their application with the keyword using. Programmers can also create their own namespaces (usually for creating reusable library code) and activate each namespace as applicable. In the above examples, we've seen simple use of the std namespace to include cin and cout, which are instances of istream and ostream (whose definitions are found in <iostream>). Let's review how we can create namespaces ourselves:

#include <iostream>
using namespace std;
namespace DataTypes
{
    int total;
    class LinkList
    {  // full class definition … 
    };
    class Stack
    {  // full class definition …
    };
};
namespace AbstractDataTypes
{
    class Stack
    {  // full class definition …
    };
    class Queue
    {  // full class description …
    };
};
// Add entries to the AbstractDataTypes namespace
namespace AbstractDataTypes   
{
    int total;
    class Tree
    {  // full class definition …
    };
};
int main()
{
    using namespace AbstractDataTypes; // activate namespace
    using DataTypes::LinkList;    // activate only LinkList 
    LinkList list1;     // LinkList is found in DataTypes
    Stack stack1;       // Stack is found in AbstractDataTypes
    total = 5;          // total from active AbstractDataTypes
    DataTypes::total = 85; // specify non-active member, total
    cout << "total " << total << "\n";
    cout << "DataTypes::total " << DataTypes::total << endl;
    return 0;
}

In the second line of code above, we use the keyword using to indicate that we'd like to use or activate the std namespace. We can utilize using to open existing libraries that may contain useful classes; the keyword using activates the namespace that a given library may belong to. Next in the code, a user-created namespace is created called DataTypes, using the namespace keyword. Within this namespace exists a variable, total, and two class definitions: LinkList and Stack. Following this namespace, a second namespace AbstractDataTypes is created and includes two class definitions: Stack and Queue. Additionally, the namespace AbstractDataTypes is augmented by a second occurrence of the namespace definition in which a variable, total, and a class definition for Tree are added.

In the main() function, first, the AbstractDataTypes namespace is opened with the using keyword. This activates all names in this namespace. Next, the keyword using is combined with the scope resolution operator (::) to only activate the LinkList class definition from the DataTypes namespace. Had there also been a LinkList class within the AbstractDataType namespace, the initial visible LinkList would now be hidden by the activation of DataTypes::LinkList.

Next, a variable of type LinkList is declared, whose definition comes from the DataTypes namespace. A variable of type Stack is next declared; though both namespaces have a Stack class definition, there is no ambiguity since only one Stack has been activated. Next, we use cin to read into to total, which is active from the AbstractDataTypes namespace. Lastly, we use the scope resolution operator to explicitly read into DataTypes::total, a name that would otherwise be hidden. One caveat to note: should two or more namespaces contain the same "name," the one last opened will preside, hiding all previous occurrences.

 

Summary

In this chapter, we reviewed core C++ syntax and non-OO language features to refresh your existing skillset. These features include basic language syntax, basic I/O with <iostream>, control structures/statements/looping, operator basics, function basics, simple user-defined types as well as namespaces. Most importantly, you are now ready to move to the next chapter, in which we will expand on some of these ideas with additional language necessities such as const qualified variables, understanding and using prototypes (including with default values), and function overloading.

The ideas in the next chapter begin to move us closer to our goal for OO programming, as many of these aggregate skills are used often and matter of factly as we move deeper into the language. It is important to remember that in C++ you can do anything, whether you mean to do so or not. There is great power in the language and having a solid base for its many nuances and features is crucial. Over the next couple of chapters, the solid groundwork will be laid with an arsenal of non-OO C++ skills, so that we may realistically engage OO programming in C++ with a high level of understanding and success.

 

Questions

  1. Describe a situation in which flush, rather than endl, may be useful for clearing the contents of the buffer associated with cout.
  2. The unary operator ++ can be used as a pre- or post-increment operator, such as i++ or ++i. Can you describe a situation in which choosing a pre- versus post-increment for ++ would have different consequences in the code?
  3. Create a simple program using a struct or class to make a user-defined type for Book. Add data members for title, author, and number of pages. Create two variables of type Book and use the dot operator . to fill in the data members for each such instance. Use iostreams to both prompt the user for input values, and to print each Book instance when complete. Use only features covered in this section.
About the Author
  • Dorothy R. Kirk

    Dorothy R. Kirk has specialized in object-oriented (OO) technologies since nearly their inception. She began as an early adopter of C++ at General Electric in research and development (R&D). After working on various projects, she was one of 10 charter members to start GE’s Advanced Concepts Center to commercially utilize OO technologies. She later started her own OO training and consulting business, specializing in OOP using C++ and Java. She additionally programs in Python. She has developed and taught many OO courses and has clients spanning industries such as academia, finance, transportation, software, embedded systems, manufacturing, and medical imaging. She has also taught C++ and OO courses at Penn State University.

    Ms. Kirk has earned a Bachelor of Science degree in Computer and Information Sciences from the University of Delaware and a Master of Science degree in Computer Science from Temple University.

    Ms. Kirk is married and has two grown children; she and her family live on a horse farm in Pennsylvania.

    Browse publications by this author
Demystified Object-Oriented Programming with C++
Unlock this book and the full library FREE for 7 days
Start now