Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
All Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Newsletter Hub
Free Learning
Arrow right icon
timer SALE ENDS IN
0 Days
:
00 Hours
:
00 Minutes
:
00 Seconds
Arrow up icon
GO TO TOP
C++ Fundamentals

You're reading from   C++ Fundamentals Hit the ground running with C++, the language that supports tech giants globally

Arrow left icon
Product type Paperback
Published in Mar 2019
Publisher
ISBN-13 9781789801491
Length 350 pages
Edition 1st Edition
Languages
Arrow right icon
Authors (2):
Arrow left icon
 Mallia Mallia
Author Profile Icon Mallia
Mallia
 Zoffoli Zoffoli
Author Profile Icon Zoffoli
Zoffoli
Arrow right icon
View More author details
Toc

Table of Contents (8) Chapters Close

About the Book 1. Getting Started FREE CHAPTER 2. Functions 3. Classes 4. Generic Programming and Templates 5. Standard Library Containers and Algorithms 6. Object-Oriented Programming 1. Appendix

Lesson 6: Object-Oriented Programming

Activity 23: Creating Game Characters

  1. Create a Character class that has a public method moveTo that prints Moved to position:

    class Character {

      public:

        void moveTo(Position newPosition) {

          position = newPosition;

          std::cout << “Moved to position “ << newPosition.positionIdentifier << std::endl;

        }

      private:

        Position position;

    };

  2. Create a struct named Position:

    struct Position {

      // Fields to describe the position go here

      std::string positionIdentifier;

    };

  3. Create two classes Hero and Enemy that are derived from the class Character:

    // Hero inherits publicly from Character: it has

    // all the public member of the Character class.

    class Hero : public Character {

    };

    // Enemy inherits publicly from Character, like Hero

    class Enemy : public Character {

    };

  4. Create a class Spell with the constructor that prints the name of the person casting the spell:

    class Spell {

    public:

        Spell(std::string name) : d_name(name) {}

        std::string name() const {

            return d_name;

        }

    private:

        std::string d_name;

    };

  5. The class Hero should have a public method to cast a spell. Use the value from the Spell class:

    public:

        void cast(Spell spell) {

            // Cast the spell

            std::cout << “Casting spell “ << spell.name() << std::endl;

        }

  6. The class Enemy should have a public method to swing a sword which prints Swinging sword:

    public:

        void swingSword() {

            // Swing the sword

            std::cout << “Swinging sword” << std::endl;

        }

  7. Implement the main method that calls these methods in various classes:

    int main()

    {

        Position position{“Enemy castle”};

        Hero hero;

        Enemy enemy;

        // We call moveTo on Hero, which calls the method inherited

        // from the Character class

        hero.moveTo(position);

        enemy.moveTo(position);

        // We can still use the Hero and Enemy methods

        hero.cast(Spell(“fireball”));

        enemy.swingSword();

    }

Activity 24: Calculating Employee Salaries

  1. We can create a class Employee with two virtual methods, getBaseSalary and getBonus, since we want to change those methods based on the type of employee:

    class Employee {

      public:

        virtual int getBaseSalary() const { return 100; }

        virtual int getBonus(const Deparment& dep) const {

          if (dep.hasReachedTarget()) {

          }

          return 0;

        }

  2. We also define a method, getTotalComp, which does not need to be virtual, but will call the two virtual methods:

        int getTotalComp(const Deparment& dep) {

          

        }

    };

  3. We then derive a Manager class from it, overriding the method for computing the bonus. We might also want to override getBaseSalary if we want to give a different base salary to managers:

    class Manager : public Employee {

      public:

        virtual int getBaseSalary() const override { return 150; }

        virtual int getBonus(const Deparment& dep) const override {

          if (dep.hasReachedTarget()) {

            int additionalDeparmentEarnings = dep.effectiveEarning() - dep.espectedEarning();

            return 0.2 * getBaseSalary() + 0.01 * additionalDeparmentEarnings;

          }

          return 0;

        }

    };

  4. Create a class Department as shown:

    class Department {

      public:

        bool hasReachedTarget() const {return true;}

        int espectedEarning() const {return 1000;}

        int effectiveEarning() const {return 1100;}

    };

  5. Now, in the main function, call the Department, Employee, and Manager classes as shown:

    int main()

    {

      Department dep;

      Employee employee;

      Manager manager;

      std::cout << “Employee: “ << employee.getTotalComp(dep) << “. Manager: “ << manager.getTotalComp(dep) << std::endl;

    }

Activity 25: Retrieving User Information

  1. We have to write the code that can be independent of where the data is coming from. So, we create an interface UserProfileStorage for retrieving the CustomerProfile from a UserId:

    struct UserProfile {};

    struct UserId {};

    class UserProfileStorage {

      public:

        virtual UserProfile getUserProfile(const UserId& id) const = 0;

        

        virtual ~UserProfileStorage() = default;

      protected:

        UserProfileStorage() = default;

        UserProfileStorage(const UserProfileStorage&) = default;

        UserProfileStorage& operator=(const UserProfileStorage&) = default;

    };

  2. Now, write the UserProfileCache class that inherits from UserProfileStorage:

    class UserProfileCache : public UserProfileStorage {

      public:

        UserProfile getUserProfile(const UserId& id) const override {

        std::cout << “Getting the user profile from the cache” << std::endl;

        return UserProfile(); }

    };

    void exampleOfUsage(const UserProfileStorage& storage) {

        UserId user;

        std::cout << “About to retrieve the user profile from the storage” <<std::endl;

        UserProfile userProfile = storage.getUserProfile(user);

    }

  3. In the main function, call the UserProfileCache class and exampleOfUsage function as shown:

    int main()

    {

      UserProfileCache cache;

      exampleOfUsage (cache);

    }

Activity 26: Creating a Factory for UserProfileStorage

  1. Write the following code that needs the UserProfileStorage class, as shown. To allow that, we provide a factory class, which has a method create that provides an instance of UserProfileStorage. Write this class making sure that the user does not have to manage the memory for the interface manually:

    #include <iostream>

    #include <memory>

    #include <userprofile_activity18.h>

    class UserProfileStorageFactory {

    public:

        std::unique_ptr<UserProfileStorage> create() const {

            return std::make_unique<UserProfileCache>();

        }

    };

  2. We want the UserProfileStorageFactory class to return a unique_ptr so that it manages the lifetime of the interface:

    void getUserProfile(const UserProfileStorageFactory& storageFactory) {

      std::unique_ptr<UserProfileStorage> storage = storageFactory.create();

      UserId user;

      storage->getUserProfile(user);

      // The storage is automatically destroyed

    }

  3. Now, in the main function, call the UserProfileStorageFactory class as shown:

    int main()

    {

      UserProfileStorageFactory factory;

      getUserProfile(factory);

Activity 27: Using a Database Connection for Multiple Operations

  1. First, create a DatabaseConnection class that can be used in parallel. We want to reuse it as much as possible, and we know we can use std::async to start a new parallel task:

    #include <future>

    struct DatabaseConnection {};

  2. Assuming there are two functions updateOrderList(DatabaseConnection&) and scheduleOrderProcessing(DatabaseConnection&), write a function that creates a DatabaseConnection and gives it to the two parallel tasks. (Note that we don’t know which task finishes first):

    void updateOrderList(DatabaseConnection&) {}

    void scheduleOrderProcessing(DatabaseConnection&) {}

  3. You must understand when and how to create a shared_ptr. You can also use the following code to write the shared_ptr correctly.

    /* We need to get a copy of the shared_ptr so it stays alive until this function finishes */

    void updateWithConnection(std::shared_ptr<DatabaseConnection> connection) {

        updateOrderList(*connection);

    }

    There are several users of the connection, and we do not know which one is the owner, since the connection needs to stay alive as long as anyone is using it.

  4. To model this, we use a shared_ptr. Remember that we need a copy of the shared_ptr to exist in order for the connection to remain valid:

    /* We need to get a copy of the shared_ptr so it stays alive until this function finishes. */

    void scheduleWithConnection(std::shared_ptr<DatabaseConnection> connection) {

        scheduleOrderProcessing(*connection);

    }

  5. Create the main function as follows:

    int main()

    {

        std::shared_ptr<DatabaseConnection> connection = std::make_shared<DatabaseConnection>();

        std::async(std::launch::async, updateWithConnection, connection);

        std::async(std::launch::async, scheduleWithConnection, connection);

    }

lock icon The rest of the chapter is locked
arrow left Previous Section
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $15.99/month. Cancel anytime
Visually different images