cpp-icon

C++ Reference

#include <iostream>

using namespace std;

int main() {
        cout << "Hello World!";
        return 0;
}
#include <iostream>

using namespace std;

int main() {
        cout << "Hello World!";
        return 0;
}
  • #include tells the pre-processor to include any set header.
  • #include <iostream>: It is called a pre-processor directive.
  • <iostream> is a header that defines the standard stream objects that input and output data.
  • std: stands for standard library.
  • main(): is a function.
  • int: is a data type.
  • cout: output stream object. For writing characters on the computer stream.
  • <<: is a stream insertion operator.

All C++ programs starts to run from the main function.
Each statement ends with a semi-colon(;).

main() function should always have return 0. If the main function return 0, it means the program run fine.

Operators

Increament Operator

  • Increases an integers value by 1.
    Syntax:
    var++ 	//postfix
    ++var 	//prefix
    
    /* Demo */
    int x = 5;
    int prefix = ++x; 	//prefix = 6
    int postfix = x++; 	//postfix = 5
    var++ 	//postfix
    ++var 	//prefix
    
    /* Demo */
    int x = 5;
    int prefix = ++x; 	//prefix = 6
    int postfix = x++; 	//postfix = 5
  • For the postfix, the value of x is assigned to it and then x is increased by 1.
  • For the prefix, the value of x is increased and then assigned to it.

Decreament operator

Syntax:

var-- 	//postfix
--var 	//prefix
var-- 	//postfix
--var 	//prefix

Logical Operators

  • && : AND
  • || : OR
  • ! : NOT

If Statement

Syntax:

if (condition) {
    //Statements
}
else if (condition) {
    //Statements
}
else {
    //Statements
}
if (condition) {
    //Statements
}
else if (condition) {
    //Statements
}
else {
    //Statements
}

A loop repeatedly executes a set of statements until a particular condition is satisfied.

While Loop

Syntax:

while (condition) {
    //Statements
}
while (condition) {
    //Statements
}

For Loop

Syntax:

for (init; condition; increment) {
    //Statements
}
for (init; condition; increment) {
    //Statements
}

Do While Loop

  • Used to ensure that a code runs at least one time before it is tested.
    Syntax:
do {
    //Statements
}
while (condition);
do {
    //Statements
}
while (condition);

Switch Statement

  • The switch statement tests a variable against a list of values, which are called cases, to determine whether it is equal to any of them.
  • default runs when none of the cases are true.
  • Syntax:
    switch (expression) {
        case value1:
            //Statement
            break;
        case value2:
            //Statement
            break;
        ...
        default:
            //Statement	
    }
    switch (expression) {
        case value1:
            //Statement
            break;
        case value2:
            //Statement
            break;
        ...
        default:
            //Statement	
    }

Declaring variables

  • A data type is required when declaring a variable.

C++ is case sensitive.

// data_type variable_name;
// data_type variable_name = value

int sum = 500;
// data_type variable_name;
// data_type variable_name = value

int sum = 500;
  • Mutiple variables can be declared by separating them with commas.

Data Types

  • Numerical data type: integers, floats.
  • Strings: letters, numbers, symbols, characters.
  • Boolean: true, false.

Integers

  • int: integer
  • signed int: hold both positive and negative numbers
  • unsigned int: hold only positive values
  • short: half the default size
  • long: twice the default size

Float

  • float(4 bytes)
  • double (8 bytes)
  • long double (16 bytes)

Float numbers are always signed.

String

  • A string is an ordered sequence of characters, enclosed in double quotation mark.
  • string: string
  • char: character
  • bool: boolean

Naming Conventions

  • Pascal Case: The first letter in the identifier and the first letter of each subsequent concatenated word are capitalised. E.g. BackColor.
  • Camel Case: The first letter in the identifier is lowercase and the first letter of each subsequent concatenated word are capitalised. E.g. backColor.

Local & Global Variables

Sample:

#include <iostream>
using namespace std;

int tuna = 69   //Global variable

int main(){
    int tuna = 10   //local variable
}
#include <iostream>
using namespace std;

int tuna = 69   //Global variable

int main(){
    int tuna = 10   //local variable
}
  • All functions can use global variables but local variables are limited to the functions they are declared in.
  • Note:
    • If you want to use a global variable while a local variable is declared with the same name, use a uniary scope resolution operator(::)

Declaring An Array

Syntax:

data_type variable_name[No._of_elements] = {};

//example
int arr[5] = {1, 5, 8, 78, 752};
data_type variable_name[No._of_elements] = {};

//example
int arr[5] = {1, 5, 8, 78, 752};

Index starts from 0
Arrays can also be initialised using a loop
If the sixe of the array is omitted, it can hold any amount of data. E.g. var[0]

Multi-Dimensional Array

  • Syntax:
    data_type name[size 1][size 2]....[size n]
    
    //example
    int var[3][4] 	//(3 x 4 array)
    // where 3 is the number of arrays and 4 is the number of elements in each array
    data_type name[size 1][size 2]....[size n]
    
    //example
    int var[3][4] 	//(3 x 4 array)
    // where 3 is the number of arrays and 4 is the number of elements in each array
  • They are initialised by specifying bracket values for each row. E.g.
    int arr[2][3] = {
        {2, 3, 4}, 
        {8, 9, 10}
    };
    int arr[2][3] = {
        {2, 3, 4}, 
        {8, 9, 10}
    };

If Statement

Syntax:

if (condition) {
    //Statements
}
else if (condition) {
    //Statements
}
else {
    //Statements
}
if (condition) {
    //Statements
}
else if (condition) {
    //Statements
}
else {
    //Statements
}

A loop repeatedly executes a set of statements until a particular condition is satisfied.

While Loop

Syntax:

while (condition) {
    //Statements
}
while (condition) {
    //Statements
}

For Loop

Syntax:

for (init; condition; increment) {
    //Statements
}
for (init; condition; increment) {
    //Statements
}

Do While Loop

  • Used to ensure that a code runs at least one time before it is tested.
    Syntax:
do {
    //Statements
}
while (condition);
do {
    //Statements
}
while (condition);

Switch Statement

  • The switch statement tests a variable against a list of values, which are called cases, to determine whether it is equal to any of them.
  • default runs when none of the cases are true.
  • Syntax:
    switch (expression) {
        case value1:
            //Statement
            break;
        case value2:
            //Statement
            break;
        ...
        default:
            //Statement	
    }
    switch (expression) {
        case value1:
            //Statement
            break;
        case value2:
            //Statement
            break;
        ...
        default:
            //Statement	
    }

Pointers

  • &(Address-of -operator) denotes an address in memory. E.g. &var.
  • A pointer is a variable with the memory address of another variable as its value.
    • sample:
      int value = 25;
      int *valuePointer;
      
      valuePointer = &fish;
      int value = 25;
      int *valuePointer;
      
      valuePointer = &fish;
  • *(asterisk) is used to declare a variable a pointer.
  • Sample:
    int *p; 	//integer
    double *p; 	//double
    float *p; 	//float
    char *p;  	//character
    int *p; 	//integer
    double *p; 	//double
    float *p; 	//float
    char *p;  	//character

For assigning do not add *.
Contents of the (dereference operator, *), returns value stored in address location. E.g. cout << "Hello" << *char

Application of Pointers

Pass by value and reference

  • Whenever a function takes in an arguement, it makes a copy of the variable and uses it - this is called pass by value.
  • But if the function takes a pointer as the arguement, it uses the variable itself without making a copy of it - this is called pass ny reference.

Demo:

#include <iostream>
using namespace std;


void passByValue(int x);
void passByReference(int *x);

int main(){
    int apple = 13;
    int orange = 13;
    
    passByValue(apple);
    passByReference(&orange);

    cout << apple << endl; 	// apple = 13
    cout << orange << endl; 	// orange = 66
}

void passByValue(int x){
    x = 99;
}

void passByReference(int *x){
    *x = 66;
}
#include <iostream>
using namespace std;


void passByValue(int x);
void passByReference(int *x);

int main(){
    int apple = 13;
    int orange = 13;
    
    passByValue(apple);
    passByReference(&orange);

    cout << apple << endl; 	// apple = 13
    cout << orange << endl; 	// orange = 66
}

void passByValue(int x){
    x = 99;
}

void passByReference(int *x){
    *x = 66;
}
  • Pointers cannot undergo normal addition. Instead of changing the memory address of the pointer, it changes what element it is pointing to.

Memory

  • In C++ memory is divided into 2 parts.
  • The Stack: All of your local variables take up memory from the stack.
  • The Heap: unused program memory that can be used when the program runs dynamically to allocate memory.

Dynamic Memory

  • It is the memory allocated at runtime.
  • It is done using the new operator.
  • Sample:
    int *p = new int;
    *p = 5;
    int *p = new int;
    *p = 5;
  • The pointer, pis stored on the stack as a local variable and holds the heap's allocated address as its value. The value of 5 is stored at the address in the heap.

Dynamic memoty must be freed using delete keyword. E.g. delete p;
Dangling pointers are pointers pointing to a non-existent memory locations

  • To delete a pointer pointing to an array, using delete [] pointer_name;

  • A function is a group of statements that perform a particular task.

Defining A Function

Syntax:

return_type function_name($args) {
    //Statements
}
return_type function_name($args) {
    //Statements
}
  • If a function does not return a value, use a return_type of void
  • A function must be declared before main.

Prototyping

  • Functions must be created before the `main` function but if you want to keep the main function above the other functions, you can use function prototyping to solve that issue.
  • This is where a function is declared before main but is defined after it.
  • Sample:
    void func();
    
    int main(){
        //some code
    }
    
    void func(){
        //some code
    }
    void func();
    
    int main(){
        //some code
    }
    
    void func(){
        //some code
    }

Function Overloading

  • It is building more than one function with the same name that takes a different data type as parameters.
  • A function cannot be overloaded if they only differ by return type.
  • Sample:
    #include <iostream>
    using namespace std;
    
    void printNumber(int x){
        cout << "I am printing an integer " << x << endl;
    }
    
    void printNumber(float y){
        cout << "I am printing a float " << y << endl;
    }
    
    int main()
    {
        int a = 54;
        float b = 32.4896;
    
        printNumber(a);
        printNumber(b);
    }
    #include <iostream>
    using namespace std;
    
    void printNumber(int x){
        cout << "I am printing an integer " << x << endl;
    }
    
    void printNumber(float y){
        cout << "I am printing a float " << y << endl;
    }
    
    int main()
    {
        int a = 54;
        float b = 32.4896;
    
        printNumber(a);
        printNumber(b);
    }

Access specifiers

  • They set access levels to particular members of a class. They are public, private and protected.
  • public: It can be accessed and modified from outside the class.
  • private: Cannot be accessed or viewed outside the class.

A public member function may be used to access the private members.

  • If no access specifier is defined, all members of a class are set to private by default.
  • Protected: It is similar to private but with one difference; it can be accessed in the derived classes.

Classes & Objects

  • A class is mainly used to group similar functions together in a program.
  • An object is used to access methods or functions in a class.
  • A method is a function that belongs to a class.
  • Sample
    #include <iostream>
    using namespace std;
    
    
    class TestClass{
        public:
            //Code written here can be used outside the class
            void coolSay(){
                cout << "Preaching to the choir" << endl;
            }
    };
    
    int main() {
        //defining an object
        TestClass testObject;
        
        testObject.coolSay();
        return 0;
    }
    #include <iostream>
    using namespace std;
    
    
    class TestClass{
        public:
            //Code written here can be used outside the class
            void coolSay(){
                cout << "Preaching to the choir" << endl;
            }
    };
    
    int main() {
        //defining an object
        TestClass testObject;
        
        testObject.coolSay();
        return 0;
    }

Making class variables public is not good programming practice, make them private.

Using Getters & Setters To Access Private Variables

Sample:

#include <iostream>
#include <string>
using namespace std;


class StringClass{
    private:
        string name;
    
    public:
        //setters are named as set<variable_name>
        void setName(string x) {
            name = x;
        }

        //getters are named as get<variable_name>
        string getName() {
            return name;
        }
};

int main() {
    StringClass test;
    test.setName("Tommy");
    cout << test.getName();
    return 0;
}
#include <iostream>
#include <string>
using namespace std;


class StringClass{
    private:
        string name;
    
    public:
        //setters are named as set<variable_name>
        void setName(string x) {
            name = x;
        }

        //getters are named as get<variable_name>
        string getName() {
            return name;
        }
};

int main() {
    StringClass test;
    test.setName("Tommy");
    cout << test.getName();
    return 0;
}

Constructors

  • It is a function that is automatically called when you instantiate an object.
  • They do not have a return type.
  • It is the same as the class name.
  • Sample:
    class TestClass{
        public:
            TestClass() {
                cout << "I am a constructor";
            }
    }
    class TestClass{
        public:
            TestClass() {
                cout << "I am a constructor";
            }
    }

Destructors

  • They are special functions that are called when an object is destroyed or deleted.
  • Sample:
    class TestClass{
        public:
            ~TestClass() {
                //some code
            }
    }
    class TestClass{
        public:
            ~TestClass() {
                //some code
            }
    }
  • They can't be overloaded.
  • They can't have return values.

Sample

main.cpp -- main file

#include <iostream>
#include "./MyClass.h"

using namespace std;

int main()
{
    MyClass obj;
    return 0;
}
#include <iostream>
#include "./MyClass.h"

using namespace std;

int main()
{
    MyClass obj;
    return 0;
}

MyClass.h -- header file: It holds the function declaration(prototypes) and variable declarations.

#ifndef MYCLASS_H
#define MYCLASS_H

class MyClass
{
public:
    MyClass();
    void myPrint();

protected:
private:
};

#endif //MYCLASS_H
#ifndef MYCLASS_H
#define MYCLASS_H

class MyClass
{
public:
    MyClass();
    void myPrint();

protected:
private:
};

#endif //MYCLASS_H

MyClass.cpp -- source file: Contains the implementation of the class and it's methods.

#include "./MyClass.h"
#include <iostream>

using namespace std;

MyClass::MyClass()
{
    cout << "Hello World";
}

void MyClass::myPrint()
{
    cout << "This is a member function";
}
#include "./MyClass.h"
#include <iostream>

using namespace std;

MyClass::MyClass()
{
    cout << "Hello World";
}

void MyClass::myPrint()
{
    cout << "This is a member function";
}
  • :: is called the binary resolution scope operator and it is used for constructor definition; It is used to define a partiulcar class' member functions, which have alredy been declared.
  • The header declares "what" a class will do, while the source file declares "how".

Selection Operators

  • #ifndef --> "If not defined"
  • #define
  • #endif --> ends the condition

Selection operators prevents a header file from being included more than once within a file.

-> is the operator used to access member functions from a pointer. Sample:

#include <iostream>
using namespace std;

class Sally {
    public:
        void printCrap() {
            cout << "Did someone say steak?" << endl;
        }
};

int main() {
    Sally obj;
    Sally *objPointer = &obj;

    obj.printCrap(); 	//accesses printCrap()
    objPointer -> printCrap(); 	//accesses printCrap() from the pointer
}
#include <iostream>
using namespace std;

class Sally {
    public:
        void printCrap() {
            cout << "Did someone say steak?" << endl;
        }
};

int main() {
    Sally obj;
    Sally *objPointer = &obj;

    obj.printCrap(); 	//accesses printCrap()
    objPointer -> printCrap(); 	//accesses printCrap() from the pointer
}

To access member functions, whenever you use an object, use a dot(.) operator while if it's a pointer, use the arrow member selection operator(->)

Syntax:

: variable(value), variable(value)
: variable(value), variable(value)

Sample:

#include <iostream>
using namespace std;


class Body{
    public:
        Body(int a, int b) 
        : regVar(a), constVar(b)
        {	
        }
    
        print() {
            cout << "The regular variable is: " << regVar << endl;
            cout << "The constant variable is: " << constVar << endl;
        }
    
    private:
        int regVar;
        const int constVar;
};

int main() {
    
    Body obj(5, 56);
    obj.print();
    
}
#include <iostream>
using namespace std;


class Body{
    public:
        Body(int a, int b) 
        : regVar(a), constVar(b)
        {	
        }
    
        print() {
            cout << "The regular variable is: " << regVar << endl;
            cout << "The constant variable is: " << constVar << endl;
        }
    
    private:
        int regVar;
        const int constVar;
};

int main() {
    
    Body obj(5, 56);
    obj.print();
    
}

  • Composition involves using classes as member variables in other classes. It serves to keep individual classes relatively simple, straightforward, and focused on performing one task. It also enables each sub-object to be self-contained and allowing for reusability

  • Sample:

class Birthday {
    public:
        Birthday(int d, int m, int y)
        : month(m), day(d), year(y)
        {
        }
    
        void printDate() {
            cout << day << "/"  << month << "/" << year << endl;
        }
    private:
        int month;
        int day;
        int year;
};

class People {
    public:
        People(string x, Birthday bo) 
        : name(x), dateOfBirth(bo)
        {	
        }
    
        void printInfo() {
            cout << name << " was born on ";
            cout << dateOfBirth.printDate() << endl;
        }
    private:
        string name;
        Birthday dateOfBirth;
};

int main() {
    Birthday birthObj(20, 30, 2002);
    People person("David", birthObj);
    person.printInfo();
}
class Birthday {
    public:
        Birthday(int d, int m, int y)
        : month(m), day(d), year(y)
        {
        }
    
        void printDate() {
            cout << day << "/"  << month << "/" << year << endl;
        }
    private:
        int month;
        int day;
        int year;
};

class People {
    public:
        People(string x, Birthday bo) 
        : name(x), dateOfBirth(bo)
        {	
        }
    
        void printInfo() {
            cout << name << " was born on ";
            cout << dateOfBirth.printDate() << endl;
        }
    private:
        string name;
        Birthday dateOfBirth;
};

int main() {
    Birthday birthObj(20, 30, 2002);
    People person("David", birthObj);
    person.printInfo();
}

  • Friend functions are non-members of a class used access all members of the class and modify it.
  • In order make a function a friend, you prototype it in the class. Sample of prototype: friend void func_name(class_name &obj)
#include <iostream>
using namespace std;

class Stank{
    public:
        Stank(){
                stinky = 0;
        }
    private:
        int stinky;

    friend void stanksFriend(Stank &sfo);
};

void stanksFriend(Stank &sfo){
    sfo.stinky = 99;
    cout << sfo.stinky << endl;
}

int main(){
    Stank bob;
    stanksFriend(bob);
}
#include <iostream>
using namespace std;

class Stank{
    public:
        Stank(){
                stinky = 0;
        }
    private:
        int stinky;

    friend void stanksFriend(Stank &sfo);
};

void stanksFriend(Stank &sfo){
    sfo.stinky = 99;
    cout << sfo.stinky << endl;
}

int main(){
    Stank bob;
    stanksFriend(bob);
}

  • It is an expression with a fixed value and cannot be changed while a program is running.
  • E.g.
    cont int x = 42;
    cont int x = 42;
  • All constants must be initialised during their declaration.

Constant Function

  • For a constant object to work, you need to declare a constant function.
  • To specify a function as a constant member, the const keyword must follow the function prototype, outside of its parameters' closing parenthesis.
    • E.g.
      class myPrintClass {
          public:
              void myPrint() const;
      }
          
      //defining a constant object
      const myPrintClass obj;
      obj.myPrint();
      class myPrintClass {
          public:
              void myPrint() const;
      }
          
      //defining a constant object
      const myPrintClass obj;
      obj.myPrint();

  • It accesses the value of a variable.
  • It is mainly used for operator overloading.
  • Sample:
    void printCrap(){
        cout << "h = " << h << endl;
        cout << "this->h = " << this->h << endl;
        cout << "(*this).h = " << (*this).h << endl;
    void printCrap(){
        cout << "h = " << h << endl;
        cout << "this->h = " << this->h << endl;
        cout << "(*this).h = " << (*this).h << endl;
  • this is a special type of pointer thst stores the memory address of the current object you're working with.

  • It allows you to use operators and change them way they are used.
  • To overload the operator, use the keyword operator and then the operator you want to overload.

Sample:

class Sally {
    public:
        int num;
        Sally() {}
        Sally(int a) {
            num = a;
        }
        Sally operator+(Sally aso) {
            Sally brandNew;
            brandNew.num = num + aso.num;
            return (brandNew);
        }
};


int main() {
    Sally a(34);
    Sally b(21);
    Sally c;
    
    c = a + b; 
    cout << c.num;
    
    //outputs 55
}
class Sally {
    public:
        int num;
        Sally() {}
        Sally(int a) {
            num = a;
        }
        Sally operator+(Sally aso) {
            Sally brandNew;
            brandNew.num = num + aso.num;
            return (brandNew);
        }
};


int main() {
    Sally a(34);
    Sally b(21);
    Sally c;
    
    c = a + b; 
    cout << c.num;
    
    //outputs 55
}

Explanation of code

// This overloads the + operator
// The function takes the current object in our case is a and
// it treats the object after the operator as a parameter of the function, in our case is b
Sally operator+(Sally aso) {
    Sally brandNew;
    // It takes the current object and adds it to another Sally object
    brandNew.num = num + aso.num;
    // returns the sum as a new Sally object
    return (brandNew);
}
// This overloads the + operator
// The function takes the current object in our case is a and
// it treats the object after the operator as a parameter of the function, in our case is b
Sally operator+(Sally aso) {
    Sally brandNew;
    // It takes the current object and adds it to another Sally object
    brandNew.num = num + aso.num;
    // returns the sum as a new Sally object
    return (brandNew);
}

  • Inheritance allows one to define a class based on another class.
  • The class whose properties are inherited by another class is called the base class.
  • The class which inherits the properties is called the derived class.

The derived class inherits all it's features from the base class, and can have its own additional features as well.

Syntax

class Derived : public Base {
    
}
// public means that all the public members of the Base class 
// become public in the Derived class.
class Derived : public Base {
    
}
// public means that all the public members of the Base class 
// become public in the Derived class.

Sample

class Mother {
    public:
        void sayName() {
            cout << "I am Saah" << endl;
        }
};

class Daughter : public Mother {
    public:
        
};

int main () {
    Mother mom;
    mom.sayName();
    
    Daughter tina;
    tina.sayName();
}
class Mother {
    public:
        void sayName() {
            cout << "I am Saah" << endl;
        }
};

class Daughter : public Mother {
    public:
        
};

int main () {
    Mother mom;
    mom.sayName();
    
    Daughter tina;
    tina.sayName();
}
  • A derived class inherits all base class methods with the following exceptions:
    • Constructors
    • Destructors
    • Overload operators
    • Friend functions
  • A class can be derived from multiple classes by specifying the base classes in a comma-separated list.
  • Whenever you make anything protected in the class:
    • Anything inside the class has access to it.
    • Any friend has access.
    • Derived class has access to it.

In inheritance, the derived class gets access to the public and protected variables.

Demo

class Derived : public Base {}
class Derived : protected Base {}
class Derived : private Base {}
class Derived : public Base {}
class Derived : protected Base {}
class Derived : private Base {}

Types

  • Public: Public members of the base class become the public members of the derived class and protected members of the base class become protected members of the derived class.
  • Protected: Public and protected members of the base class become protected members of the derived class.
  • Private: Public and protected members of the base class become private members of the derived class.

Note:

  • if no access specifier is used when inheriting classes, the type becomes private by default.
  • During inheritance:
    • Constructors: The base class constructor is called first.
    • Destructors: The derived class destructor is called first.

  • Polymorhism means "having many forms".
  • It occurs in a direct hierachy of classes and they are related by inheritance.
  • In C++, it means that a call to a member function will cause a different implementation to be executed depending on the type of object that invokes the function.

Demo

class Enemy {
    protected:
        int attackPower;
    public:
        void setAttackPower (int a) {
            attackPower = a;
        }
};

class Ninja : public Enemy {
    public:
        void attack() {
            cout << "I am a ninja, chop! -" << attackPower << endl;
        }
};

class Monster : public Enemy {
    public:
        void attack() {
            cout << "Monster must eat!  -" << attackPower << endl;
        }
};

int main () {
    Ninja n;
    Monster m;
    Enemy *enemy1 = &n;
    Enemy *enemy2 = &m;
    enemy1->setAttackPower(28); 
    enemy2->setAttackPower(50);
    
    n.attack();
    m.attack();
}
class Enemy {
    protected:
        int attackPower;
    public:
        void setAttackPower (int a) {
            attackPower = a;
        }
};

class Ninja : public Enemy {
    public:
        void attack() {
            cout << "I am a ninja, chop! -" << attackPower << endl;
        }
};

class Monster : public Enemy {
    public:
        void attack() {
            cout << "Monster must eat!  -" << attackPower << endl;
        }
};

int main () {
    Ninja n;
    Monster m;
    Enemy *enemy1 = &n;
    Enemy *enemy2 = &m;
    enemy1->setAttackPower(28); 
    enemy2->setAttackPower(50);
    
    n.attack();
    m.attack();
}

  • It is a function or method whose behavior can be overriden within an inheriting class by a function.
  • It is a base class function that is declared by the keyword virtual.

Demo

class Enemy {
    public:
        virtual void attack() {}
};

class Ninja : public Enemy {
    public:
        void attack() {
            cout << "ninja attack!" << endl;
        }
};

class Monster : public Enemy {
    public:
        void attack() {
            cout << "monster attack!" << endl;
        }
};

int main () {
    Ninja n;
    Monster m;
    // since a ninja and a monster are a specific types of enemy, 
    // an Enemy object can be created and it's pointer is set equal to the 
    // memory address of their objects respectively
    Enemy *enemy1 = &n;
    Enemy *enemy2 = &m;
    
    enemy1->attack();
    enemy2->attack();
}
class Enemy {
    public:
        virtual void attack() {}
};

class Ninja : public Enemy {
    public:
        void attack() {
            cout << "ninja attack!" << endl;
        }
};

class Monster : public Enemy {
    public:
        void attack() {
            cout << "monster attack!" << endl;
        }
};

int main () {
    Ninja n;
    Monster m;
    // since a ninja and a monster are a specific types of enemy, 
    // an Enemy object can be created and it's pointer is set equal to the 
    // memory address of their objects respectively
    Enemy *enemy1 = &n;
    Enemy *enemy2 = &m;
    
    enemy1->attack();
    enemy2->attack();
}

Virtual functions are overriden by polymorphic classes.

Pure Virtual Functions

  • They are virtual functions without definitions
  • Syntax:
    virtual return_type function_name() = 0;
    virtual return_type function_name() = 0;
  • The = 0 tells the compiler that the function has no body.
  • Every derived class inheriting from a base class with a pure virtual function must override that function, else the code fails to compile and results in an error when you try to instantiate an object of the derived class.

Abstract Class

  • It is a class with a pure virtual function in it.

Using one data type at a time

Syntax:

template <class T>
    T func_name(T a) {
    return a;
}
template <class T>
    T func_name(T a) {
    return a;
}
  • T is not a specific data type but a generic type of data.

A generic class is a variable for the type of data instead of the value itself.
In this sense, T is a variable for a data type.

Demo

template <class T>
    T sum(T a, T b) {
    return a + b;
}

int main() {
    int x = 7, y = 3, z;
    z = sum(x, y)
    cout << z << endl;
}
template <class T>
    T sum(T a, T b) {
    return a + b;
}

int main() {
    int x = 7, y = 3, z;
    z = sum(x, y)
    cout << z << endl;
}

If you need a function to do the same thing and work with multiple types of data, you can build a template function.

Using multiple data types at a time

  • To declare multiple generic data types, use a comma-separated list.
  • E.g.
    template <class T, class U>
    template <class T, class U>
  • Sample:
    template <class T, class U>
    U smaller(T a, U b) {
        return (a < b ? a : b); 
    }
    
    int main(){
        cout << smaller(1, 4.25) << endl;
    }
    template <class T, class U>
    U smaller(T a, U b) {
        return (a < b ? a : b); 
    }
    
    int main(){
        cout << smaller(1, 4.25) << endl;
    }

When you declare a template parameter, you must use it in your function else the compiler will complain.

Syntax:

template <class T>
class MyClass {};
template <class T>
class MyClass {};

Demo:

template <class T>
class Pair {
    private:
        T first, second;
    public: 
        Pair(T a, T b) : first(a), second(b) {}
    
        T bigger();
};

template <class T>
T Pair<T>::bigger() {
    return (first > second ? first : second);
}


int main() {
    Pair <int> obj(69, 245);
    cout << obj.bigger() << endl;
}
template <class T>
class Pair {
    private:
        T first, second;
    public: 
        Pair(T a, T b) : first(a), second(b) {}
    
        T bigger();
};

template <class T>
T Pair<T>::bigger() {
    return (first > second ? first : second);
}


int main() {
    Pair <int> obj(69, 245);
    cout << obj.bigger() << endl;
}

bigger() can be declared in the class:

 T bigger() {
     return (first > second ? first : second);
   }
 T bigger() {
     return (first > second ? first : second);
   }

Things to note

  • If you're declaring any function member outside the declaration of a class, you need to have the template definition again.
  • <T>(blank generic data type) tells the compiler that the function's template parameter is the same as used in the class.
  • When creating the objects, you have to explicitly declare the data type. E.g:
    Pair <int> obj(69, 245);
    Pair <int> obj(69, 245);

  • It allows for the definition of a different implementation of a template when a specific type is passed as a template arguement.

Syntax

template <>
class MyClass <char> {
    public:
        MyClass(char x) {};

// where `char` can be any data type
template <>
class MyClass <char> {
    public:
        MyClass(char x) {};

// where `char` can be any data type

Demo

template <class T>
class MyClass {
    public:
        MyClass(T x) {
            cout << x << " is not a character" << endl;
        }
};


// using template specialisation
// testing for data type `char`
template <>
class MyClass <char> {
    public:
        MyClass(char x) {
            cout << x << " is a character" << endl;
        }
};


int main() {
    MyClass <int> obj1(7);
    MyClass <double> obj2(7.25);
    MyClass <char> obj3('d');
}
template <class T>
class MyClass {
    public:
        MyClass(T x) {
            cout << x << " is not a character" << endl;
        }
};


// using template specialisation
// testing for data type `char`
template <>
class MyClass <char> {
    public:
        MyClass(char x) {
            cout << x << " is a character" << endl;
        }
};


int main() {
    MyClass <int> obj1(7);
    MyClass <double> obj2(7.25);
    MyClass <char> obj3('d');
}

  • Problems that happen during program execution are called exceptions.
  • C++ exception handling is built upon 3 keywords: try, catch and throw.
    • In order to throw an exception, error numbers can be used. E.g. throw 0;.
    • To handle the error, you need to catch the error (Which is the error number).
    • This is done using the catch keyword and enter a block of code to run if an error occurs.

Syntax:

try {
    // code
} catch(...) {
    // code to handle exceptions
}
try {
    // code
} catch(...) {
    // code to handle exceptions
}

Sample:

try {
    int num1 = 55;
    int num2 = 0;
    
    if(num1 > num2) {
        throw 0;
    }
} catch(int x) {
    cout << "Math error: cannot divide by " << x << endl;
} 
try {
    int num1 = 55;
    int num2 = 0;
    
    if(num1 > num2) {
        throw 0;
    }
} catch(int x) {
    cout << "Math error: cannot divide by " << x << endl;
} 

  • C++ uses fstream library to allow for the creating, reading and/or writing of files. A header file: <fstream> needs to be included to access it.
  • Three data types are defined in fstream:
    • ofstream: Output from file stream that creates and writes information to files.
    • ifstream: Input file system that reads information from files.
    • fstream: General filestream, with both ofstream and ifstream capabilities that allow it to create, read and write information to files.

An object needs to be created since cpp cannot work with files directly.

Sample:

#include <iostream>
#include <fstream>
using namespace std;

# Create a file object
ofstream objName;

# Open the file
# If a file opened does not exist, a new file is created
objName.open("das.txt");

# To output into file
objName << "I am being saved in a file!\n";

## At the end of the program, close the file
# To close the file
objName.close();
#include <iostream>
#include <fstream>
using namespace std;

# Create a file object
ofstream objName;

# Open the file
# If a file opened does not exist, a new file is created
objName.open("das.txt");

# To output into file
objName << "I am being saved in a file!\n";

## At the end of the program, close the file
# To close the file
objName.close();

Tips When Working With Files

  • You can create an object and pass the filename as an arguement in the constructor
    Sample:
ofstream fileObj("filename");
ofstream fileObj("filename");
  • It's good practice to close file objects after working with them. E.g. fileObj.close()
  • In working with files, the output of a code can be stored in them.
  • isopen() function: It returns true if an object is associated with a file. It is used to check if a file is opened.
    Sample:
if(fileObj.is_open()) {
    cout << "The file is open" << endl;
} else {
    cout << "The file is not open" << endl;
}
if(fileObj.is_open()) {
    cout << "The file is open" << endl;
} else {
    cout << "The file is not open" << endl;
}

Before working with file objects, check to see if they are opened first.

Making A Custom File Structure

Sample:

int main() {
    ofstream fileObj("filename.txt")
    cout << "Enter ID, Name and Money" << endl;
    // cout << "Press Ctrl+Z to quit\n" << endl;

    int ID;
    string name;
    double money;

    while(cin >> ID >> name >> money) {
    fileObj << ID << " " << name << " " << money << endl; 
    }
}
int main() {
    ofstream fileObj("filename.txt")
    cout << "Enter ID, Name and Money" << endl;
    // cout << "Press Ctrl+Z to quit\n" << endl;

    int ID;
    string name;
    double money;

    while(cin >> ID >> name >> money) {
    fileObj << ID << " " << name << " " << money << endl; 
    }
}

How To Read Custom Data

  • To read data in from a file, use ifstream or fstream object.
  • Whenever working with files, there's something called a file pointer. It keeps track of where in the file cpp is working with.
    Sample:
ifstream fileObj("filename.txt");

int ID;
string name;
double money;

while(fileObj >> id >> name >> money) {
    cout << ID << ", " << name << ", " << money << endl;
}
ifstream fileObj("filename.txt");

int ID;
string name;
double money;

while(fileObj >> id >> name >> money) {
    cout << ID << ", " << name << ", " << money << endl;
}

When the file pointer gets to the end of the file, it automatically returns false.

  • When the file pointer reaches the end of the file, the fileObj is going to be deleted automatically.

The deconstructor calls the close() method.

File Opening Modes

An optional parameter of open() defines the mode in which the files are opened.
Syntax:

open("name of file", mode_parameter)
open("name of file", mode_parameter)
Mode Parameter Meaning
ios::app append to the end of file
ios::ate got to the end of file on opening
ios::binary file open in binary mode
ios::in open file for read-only
ios::out open file for writing only
ios:: delete contents of files if exists

Modes can be combined using OR(|) bitwise operator. #

  • endl : ends a line. ('\n' also ends a line).
  • cin: is called the input stream object.
  • >>: is called stream extraction operator.
  • // for single line comments.
  • /* */ for multi-line comments.

In the current C++, it is not compulsory to add return 0 at the last line of int main function.

  • sizeof function determines the size of a variable in bytes. E.g. sizeof(var)
  • (*this) means deferencing a pointer. (where this can be any pointer)