Author:
Michael Massaro
Subject:
Computer Science
Material Type:
Reading
Level:
Academic Lower Division
Tags:
  • Abstraction
  • C++
  • C++ Programming
  • Classes
  • Data Hiding
  • Inheritance
  • Linked Lists
  • Not Reviewed
  • Pointers
  • Polymorphism
  • Queues
  • Stacks
    License:
    Creative Commons Attribution No Derivatives
    Language:
    English
    Media Formats:
    Text/HTML

    C++ Guide for Beginners

    C++ Guide for Beginners

    Overview

    This OER is designed to give readers a further understanding of coding and C++. Concepts covered include:

    • Pointers
    • Classes
    • Linked Lists
    • Stacks
    • Queues
    • Abstraction
    • Data hiding
    • Polymorphism
    • Inheritance

    Pointers

    Pointers are variables that store the memory address of a value. In order to get the memory address of a variable, use the & operator. But when declaring a pointer variable, use the * operator. Below is a code snippet demonstrating the difference between declaring normal variables and declaring pointers.

    With a basic understanding of pointers, we can begin to discuss its applications.

    • Dynamic memory allocation - Pointers can be used to dynamically allocate memory. 
    • Return multiple values - In a void function, pointers can be used to carry over multiple values.
    • Access array elements - C++ compilers internally use pointers when accessing elements in an array. The compiler internally converts arr[5] into *(arr+5), which both output the same element.
    • System level programming - C++ pointers are very efficient and memory allocation is a necessary tool in lower level programming.
    • Implement data structures - Pointers can be used to create data structures, such as trees and linked lists. In another tab from this guide, I will discuss linked lists using pointers in further detail.

    Classes

    Classes

    Classes are user-defined data types that are the main force behind object oriented programming in C++. Object oriented programming (OOP) is based on the concept of objects. An object is an instance or declaration of a class in C++ and it will typically hold a combination of methods (functions) and attributes (variables). This section of the guide will walk through a basic class I made in order to learn not only the basics of a class, but also good practices and methodologies to keep in mind.

    Attributes, Data Hiding, and Abstraction

    The first part of making a class is defining what attributes it has. For this simple example, we will make an animal class that will have the attributes of its scientific name and its length in inches. Notice that we are simply declaring that this class has these attributes and are not initializing these attributes with values yet. More on that in the Constructor section of this tab.

    Something else important to note about these attributes is that they are private. This means that functions or algorithms outside of those declared within the class cannot alter these values. Making your class attributes private follows good object oriented programming methodologies, such as abstraction and data hiding.

    Data hiding can be defined as an object oriented programming technique that hides internal data of the object from other parts of the program. This also follows the concept of encapsulation, which promotes OOP by binding together the data and methods of an object, thus preventing outside interference and misuse. By making your attributes private and only modifiable by the object itself, you are following good OOP practices by using the concepts of data hiding.

    Abstraction can be defined as only extracting relevant information to hide the complexity of the object. Privatizing our class attributes not only prevents misuse of data via data hiding, but it also makes the object appear less complex to the user via abstraction.

    Methods

    The second and last part about making a class is defining its functions. Since we are following good OOP practices, we will need methods that will help us modify and help us access our private attributes from objects we create. We can also add more methods beyond these for added utility. We will also need constructors to define our attributes upon object creation. Notice that these methods are public; this is because we want to be able to create objects from our class and call these methods with each of our objects.

    • Modifiers - Also known as setters, these types of methods change the value of an object's attributes. In our example above, this can be used to change the animal's length or name attribute.
    • Accessors - Also known as getters, these types of methods retrieve the value of an object's attributes. Since we cannot simply use the animal's attributes freely due to data hiding, this is how you can retrieve the object's data for the rest of your program to use.
    • Constructors - These methods are called upon object creating. In other words, when you initialize an Animal variable, the constructor will automatically be called. In the example above, there are two constructors, one that takes parameters and one that does not. Which one is called depends on whether or not you use parameters when creating a new object. If you don't, the scientific name will automatically be initialized as Chinchilla Lanigera and the length will automatically initialized to 12 inches.

    Defining and Using an Object

    • Create Objects (Constructors) - Creating an object from a class is very similar to initializing a normal variable if you are using the default constructor. By declaring Animal chinchilla with no parameters, we call our constructor that has no parameters in its definition. That means that its scientificName will default to "Chinchilla Lanigera" and its inchLength will default to 12. Since we initialized Animal kookaburra with parameters, its scientificName will be "Dacelo Novaeguineae" and its inchLength will be 18.
    • Accessors - The example above shows how to use the attributes of Animal object while obeying good OOP practices. We can call the accessors to be used in an if-statement and then output longer animal of the two using another accessor. While practically if we wanted to compare the size of two animals, we would make a method to do so, I wanted to demonstrate how to call objects and use them in your program. The output result is Dacelo Novaeguineae is longer.
    • Modifiers - The last part of the program is modifying the values while also following data hiding guidelines. We extended the length of the chinchilla to 19 inches, which would mean if we compared the sizes again in the Accessors section the chinchilla would be the scientific name output. We also change the scientific name of the kookaburra to only have the first half of the genus.

    Linked Lists

    Linked Lists

    Let's combine what we learned from Pointers and Classes and make a linked list object. But first, let's define what a linked list is.

    Nodes

    Linked lists are data structures that holds multiple elements, similar to an array, which have two key elements in every element (or node):

    • 1) Data - The value of a single element.
    • 2) Pointer - Usually named "next," the pointer serves as a reference in memory and are linked to each other to create an ordered data structure.

    Before we make a linked list class, we need to define a struct with those two key attributes in order to create a node. One element of a linked list object will be a node, which holds data and the position in memory (using a pointer) of the next element or node.

    Linked List Class: Create and Print

    Similar to the animal class in our previous example, we are following good OOP practices by defining our variables (which are both Node pointers) for our class privately. The head and the tail are used to keep track of where we are in the linked list during linked list operations.

    • Head - The beginning or top node of the linked list. 
    • Tail - The end or bottom node of the linked list. 

    Next, we will go over the methods listed in this linked list. This linked list only has the ability to construct itself (initialized at NULL), add nodes to it, and print the nodes in order from head to tail. This linked list class doesn't have the ability to remove nodes or to check how many nodes are in this linked list, but it's worthy noting that a typical linked list would have the ability to do so and even more. This is just for a brief example.

    • createNode (string d) -  This method will append a node to the tail of the linked list with the data value of the passed string parameter. First, it checks if it's the first node to be added, which if that is the case will simply make that node the head and the tail. However, in all other cases it will append that node and the parameter data to the tail.
    • print() -  This method cycles through the linked list from the beginning (head) and outputs the data in all elements until it reaches the end of the linked list (tail).

    Defining and Using a Linked List

    This is an example on how to use this linked list class.

    • First, start by creating an object, in this case we called it animals. You'll want to note that the linked list class will automatically call the constructor at this time, which initializes the head and tail to NULL.
    • Second, we append notes to the linked list using its method called createNode. We pass in the name of the animal using this method's parameters.
    • Third, we print out the linked list from head to tail. This will print out Chinchilla, Kookaburra, and Leptopelis in the same order that it was appended.

    Stacks & Queues

    Stacks & Queues

    Stacks and queues are both data structures that hold multiple elements, like an array or a linked list. In fact, both stacks and queues are often created using a linked lists object similar to example in the Linked Lists tab. The difference between a stack and a queue is the order in which they follow to add and remove elements.

    Stacks follow the order called LIFO, which stands for Last In First Out. This means that the most recent element added to the stack is also the first element to be removed. A real world application that uses this conceptual logic is a stack of pancakes; typically the last pancake to be added on top of the stack is the first one to be eaten.

    Queues follow the order called FIFO, which stands for First In First Out. This means that the least recent element added to the stack is the first element to be removed. A real world application that uses this conceptual logic is a line of people; typically the person who has been in the queue the longest is the next person to be served.

    In C++, stacks and queues typically have these class functions in order to operate:

    • size() - This function returns an integer that is equal to how many elements are inside the stack or queue. This can be an important function to call if you only want to perform certain functions if the stack or queue has a certain amount of elements in it. For example, you cannot pop elements off a stack or queue if the stack or queue is already empty. 
    • peek() - This function returns the value of the next element to be removed. A stack will return the most recently added element, as opposed to a queue which will return the oldest element.
    • pop() - This function returns the value of the next element to be removed, similarly to peek(), and also removes that element. 
    • push(e) - This function adds an element with the value of e to the stack or queue. Returns nothing.

    Inheritance & Polymorphism

    Inheritance & Polymorphism

    Inheritance in C++ is when a new class is made that derives the properties from an older class. This makes creating and maintaining classes easier because we don't have to write completely new data members. A class that is derived from another class is called a sub class, while the class that the sub class is deriving from is the super class.

    Polymorphism is when you change the behavior of the super class with the sub class. In other words, if you create a method in a sub class that has the same name and parameters as a method in its super class, an object derived from the sub class will still prioritize its method despite it inheriting a method of the same name from its super class.

    Below is an example of one super class and two sub classes to help understand these definitions:

    Inheritance & Polymorphism Syntax

    Please note that I took away certain methods from Animal (relative to the Classes tab of this guide) simply to make the lessons of inheritance and polymorphism more clear. As this class stands, it is incomplete due to not having any modifying methods, among other attributes and methods.

    In this example, Animal is the super class while Chinchilla and Kookaburra are the sub classes. Both Chinchilla and Kookaburra inherit the private variables that Animal has, as well as its constructor and getScientificName() method. However, each class has a method called diet, which indicates the food that each animal eats. This is where polymorphism comes in. Do you think that Kookaburra and Chinchilla will inherit the Animal diet() method, or will it use its own?

    If you guessed that it will use its own, you are correct! This is essentially polymorphism in action. We can see that the sub class of Kookaburra not only inherited the method getScientificName(), but also inherited the super class Animal's constructor because its scientificName defaulted to Animalia upon object initialization. We can also see polymorphism in action due to the Chinchilla object prioritizing its own method of diet() over despite being a sub class of Animal.