$40
Contents
I Inheritance 2
1 Overview 2
1.1 Description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.2 Abstract Base Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.3 Multiple Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.4 The Diamond Problem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.4.1 How to resolve the diamond problem . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.5 Public and Private Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.5.1 Accessing members of base class(es) . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.6 Virtual . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 1.7 Polymorphism . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2 Assignment Specifics 6
2.1 Bank Account . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.2 Checking Account . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.3 Savings Account . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.4 Investment Account . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 2.5 Tips . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
II Maps... and other 8
3 Overview 8
3.1 Maps in C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
3.2 Upcasting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 3.3 Functors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
4 Assignment Specifics 9
4.1 Description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
4.2 Additional Notes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
1
Part I
Inheritance
1 Overview
In this part of the assignment, you’re going to create a series of classes to represent bank accounts. While the classes themselves are all simple, you will be using inheritance and the concept of polymorphism to make them functional with the given main code. You will also create classes which make use of multiple inheritance, as well as private inheritance.
1.1 Description
The basic idea of inheritance is that you have a base class, and you create new classes which derive from that base class. One common use of inheritance is to reuse data and functions: if a base class defines those things, then the derived class doesn’t have to; it inherits them, so in effect, you get "free" code in that class.
Another use of inheritance is to define a class which serves as what other programming languages would call an interface. In C++, the keyword interface doesn’t exist, but some of the classes you create here will serve the same purpose. An interface defines how a class should look on the outside.
The first class shown here will serve as interfaces; all the other classes will derive from it. In this way, all classes in this assignment are bank accounts. Some types of inheritance model the “Is-a” relationship. A triangle IS A shape. A circle IS A shape as well.
Other types of inheritance model a “has-a” relationship. A car, for example, has an engine—but it isn’t an engine. This type of relationship can still be created, but the process is a bit different.
1.2 Abstract Base Class
An Abstract Base Class (ABC) is a class you never want to create an instance of; it doesn’t have enough information to be useful on its own. An ABC could have any number of functions or variables, whether public, protected, or private. You cannot create an instance of an abstract base class.
Perhaps you are creating a program that needs to store data about students and faculty members. They share similar data (name, age, email address, etc.), but have their own unique data as well. You might create 3 classes:
To create an abstract base class, at least one function in the class must be a pure virtual function. A pure virtual function is one that:
1. Have the virtual keyword before the return type
2. Has = 0 at the end of the prototype
3. Has no function definition (i.e. no body) – the only exception to this is the destructor. You MUST have a body on a destructor, pure virtual or otherwise.
For example, our display function is a pure virtual function:
1.3 Multiple Inheritance
1.3 Multiple Inheritance
While many languages do not allow multiple inheritance, C++ does! The basic concept is the same. You have multiple base classes, and a single class can derive from some or all of them, inheriting the data members and functions of each base class.
1.4 The Diamond Problem
An issue with multiple inheritance is the dreaded “diamond problem.” This comes about when a derived class inherits from two base classes, which each derive from the same parent base class. Consider this:
Figure 1.1: Diamond Problem
In this example, you want FlyingCar to inherit both driving and flying functionality... but you unfortunately inherit Vehicle functionality twice!
1.4.1 How to resolve the diamond problem
You can fix the issue of the diamond problem by using virtual inheritance. In the above example, the class declarations might look like this:
With virtual inheritance, the "in-between" classes would add the virtual keyword to the inheritance:
This ensures that FlyingCar would only inherit ONE instance of anything Car and Airplane inherited from Vehicle. For more information:
https://en.wikipedia.org/wiki/Virtual_inheritance https://isocpp.org/wiki/faq/multiple-inheritance#virtual-inheritance-where
1.5 Public and Private Inheritance
1.5 Public and Private Inheritance
Perhaps the most common type of inheritance is public inheritance. It represents an "is-a" relationship between classes. The derived class is a base class. For example:
We would say that the Car (derived class) IS A Vehicle (base class). A SavingsAccount IS A BankAccount. A Button IS A UIControl, etc. If class inherits from another class using private inheritance, however, it models a "has a" relationship. This is also sometimes referred to as composition. For example:
The only thing the Car class can access of the Engine object is public members and functions - here’s where the accessor functions of a class would come into play.
1.5.1 Accessing members of base class(es)
To access the functions or variables of a base class, you must specify the name of the class, and then the thing you are trying to access. So in the case of the car and its engine, you would do something like this:
Reference: https://isocpp.org/wiki/faq/private-inheritance
1.6 Virtual
We’ve gone over different use cases of virtual, that it’s necessary for solving the diamond problem, that ABC’s must have at least one pure virtual function, etc. So what is it?
Let’s start with virtual inheritance. This is specifically when you specify a virtual parent class. It would look something like this: "Derrived : virtual public Base". We’ve already gone over the fact that this is necessary for solving the diamond problem. But why? The reason is that virtual inheritance tells the compiler to only ever include one instance of the class within derived classes. More accurately, it tells the compiler to check if the parent class has already been inherited and to use that instance as the parent rather than making a new one.
Let’s move on to virtual methods. In this case we are telling the compiler to make what’s called a vtable for any class with this method. You don’t have to know much about what the vtable does but I do recommend looking into it as it helps with a lower-level understanding. With that said, what you should know is that the result of using a vtable is the ability to override and call overriden behavior from a downcasted parent declaration. This means running the code snippet below will result in the child behavior not the parents!
As a take away, the virtual keyword seems ensure that there is only one instance of something in a class. Whether that means one definition for a function (regardless the static dispatch) or one instance of a parent within the child class.
1.7 Polymorphism
1.7 Polymorphism
One important concept in object-oriented programming is that a base-class pointer can point to any object which derives from that base class. For example:
Following that same concept, we could extend that to something like the following:
What polymorphism allows you to do is call a function from one of those objects and depending on what the pointer is pointing to the correct function will be called.
Given the previous array, code like the main function bellow would print out "I’m a sports car!".
Polymorphism is the concept that allows you to write code like that, without knowing exactly what type of object you are pointing to. Since cars[1] points to a SportsCar, the call to Identity() will determine that the SportsCar version of the function should be used. The virtual keyword is required on the base class version of the function in order to make this functionality possible.
For more on polymorphism: http://www.cplusplus.com/doc/tutorial/polymorphism/
2 ASSIGNMENT SPECIFICS
2 Assignment Specifics
2.1 Bank Account
BankAccount is an abstract base class. Because at least one of the functions in this class are pure virtual functions (virtual functions with no definition). This base says that all BankAccounts can calculate an amount, display their data, and recieve a deposit. Each derived class can define HOW they do each of these. This class will not require a virtual destructor. A virtual destructor is used to make sure child destructors (if necessary) are called even if the deleted variable is upcasted as a parent class.
2.2 Checking Account
CheckingAccount derives from the BankAccount class (a CheckingAccount IS A BankAccount). This class, however, is not an abstract base class. This means we now must define any previous virtual functions.
2.3 Savings Account 2 ASSIGNMENT SPECIFICS
2.3 Savings Account
The savings account class will be treated similarly to the Checking account. All the same virtual functions must be overridden, a new private variable amount must be added as well as a new protected method setAmount().
There is also a new behavioral function to add: CompoundEarnings(), which will return a float (the earned amount). This method should take in a positive float and set the amount in the account to amount*(1+percent). This is how the account will earn interest. While this seems like the same situation as with the Checking account, this function will change in the future investment account.
In addition, you must also implement Transfer(). This function will return a boolean representing the operations success. It will take in a checking account object and a float then transfer ’float’ amount from the savings account to the passed in checking account (modifying parameters... where have I heard that before).
2.4 Investment Account
Now it’s time for the more complicated account class of the 4. The premise of this class is an account that for the most part is a checking account but has a sort of savings account. This savings account will be the investment side of the account. The idea is for any earnings from the investment side to be immediately available in a checking account format as to not have the user worry about transferring money at all.
With that said here are a few things to look out for:
• getAmount should give the total amount in both!
• initial values and any deposits go to the savings account not to the checking!
• You will have to override quite a few functions here!
• Transfer should only take one ’float percent’ and transfer from this savings to this checking!
2.5 Tips
A few tips about this assignment:
• MOST IMPORTANT: One very necessary distinction to make is that of getAmount() and amount. Specifically because getAmount() is virtual calling it will get the definition of the invoking object which is not necessarily the current class. That is to say calling it within the CheckingAccount class will return the total amount within an InvestmentAccount object if that is the invoking object.
• Start with one class at a time. It is important to keep future classes in mind but trying to work from the bottom up can mean a lot of back and forth.
3 OVERVIEW
Part II
Maps... and other
3 Overview
For this assignment, you must write main(int argc, char** argv) and the functor, AccountReader. As long as you implemented everything correctly in part 1 this part will come a lot easier!
3.1 Maps in C++
Thankfully the map class is not one we have to right ourselves! It’s included in the STL specifications meaning all we have to do is #include<map>. There is also the unordered_map which uses hashing functions to have a slightly better performance, but to produce consistent output with options 1 and 2 we will be using the map class. To help get you started here is an example of looping through a map:
3.2 Upcasting
Upcasting is the process of converting an object which is declared as a parent class into one declared as the child class. Notice that this changes what’s called the static dispatch, you can think of this as what you declare a variable. However, without checking that this object actually is the child class we want to cast to, this is a dangerous thing to do. To safely upcast we will use dynamic_cast in the following format:
3.3 Functors
We will be using functors in this lab! Functors are a neat way to generalize functions. For example, if you need to have a function that calculates gravitational force you might need different constants for gravity. So instead of having to pass a parameter every time we call the function, we can use a functor!
The following code is for this example:
4 ASSIGNMENT SPECIFICS
4 Assignment Specifics
4.1 Description
You are given a csv file (Comma Separated Values) with rows representing different bank accounts. You must read from these rows and store their information within a new object of it’s respective account class. Then store that object within two maps. You will have store it as a pointer to ensure polymorphism is maintained. The keys you will need to look up with are the account owner’s name and the account’s ID. You will code a functor that takes in the file path of the csv file.
To make things easier you should have the following 2 maps in your functor:
• Map 1: ID lookup map. This map will use the owners id as the key and the owners Bank Account as a value (BankAccount*)
• Map 2: Name lookup map. This map will use the owners name as the key and the owners Bank Account as a value (BankAccount*) The format of the file is as follows:
Type Name Amount ID
2 Derek Pearce 1773 1009
1 Ria Marshall 3288 1010
3 Ronan Walker 8971 1011
3 Eric Carr 4762 1012
et c...
The type number will be one of the ints 1, 2, or 3 representing Checking, Savings, and Investment accounts respectively
The options you will have to read (cin) and implement within your call operator:
1. Display all accounts
2. Display all of account type
2.1. Checking Accounts
2.2. Savings Accounts
2.3. Investment Accounts
3. Find account
• Integer input for ID search (use stoi!)
• String input for name search (HAS TO BE FULL NAME)
• Not Found
4.2 Additional Notes
• **IMPORTANT** You are expected to use CLI to get the file path from the main and pass it to the functor. The program will be called in the following format:
– ./main.out path/to/accounts.csv
• We are using stdin (aka cin) for option selection. HOWEVER, note that cin >> name is NOT the same as getline(cin, name)... this important for when the input has spaces!
• Because this part requires you to create new variables and store their pointers in maps, we are working with dynamic memory. As such you are expected to delete the pointers also!