C++ friend Function and friend Classes

In this article, you’ll learn to create friend function and class in C++, and use them efficiently in your program.

One of the important concepts of OOP is data hiding, i.e., a nonmember function cannot access an object’s private or protected data.

But, sometimes this restriction may force programmer to write long and complex codes. So, there is mechanism built in C++ programming to access private or protected data from non-member functions.

This is done using a friend function or/and a friend class.


friend Function in C++

If a function is defined as a friend function then, the private and protected data of a class can be accessed using the function.

The complier knows a given function is a friend function by the use of the keyword friend.

For accessing the data, the declaration of a friend function should be made inside the body of the class (can be anywhere inside class either in private or public section) starting with keyword friend.


Declaration of friend function in C++

class class_name
{
    ... .. ...
    friend return_type function_name(argument/s);
    ... .. ...
}

Now, you can define the friend function as a normal function to access the data of the class. No friend keyword is used in the definition.

class className
{
    ... .. ...
    friend return_type functionName(argument/s);
    ... .. ...
}

return_type functionName(argument/s)
{
    ... .. ...
    // Private and protected data of className can be accessed from
    // this function because it is a friend function of className.
    ... .. ...
}

Example 1: Working of friend Function

/* C++ program to demonstrate the working of friend function.*/
#include <iostream>
using namespace std;

class Distance
{
    private:
        int meter;
    public:
        Distance(): meter(0) { }
        //friend function
        friend int addFive(Distance);
};

// friend function definition
int addFive(Distance d)
{
    //accessing private data from non-member function
    d.meter += 5;
    return d.meter;
}

int main()
{
    Distance D;
    cout<<"Distance: "<< addFive(D);
    return 0;
}

Output

Distance: 5

Here, friend function addFive() is declared inside Distance class. So, the private data meter can be accessed from this function.

Though this example gives you an idea about the concept of a friend function, it doesn’t show any meaningful use.

A more meaningful use would to when you need to operate on objects of two different classes. That’s when the friend function can be very helpful.

You can definitely operate on two objects of different classes without using the friend function but the program will be long, complex and hard to understand.


Example 2: Addition of members of two different classes using friend Function

#include <iostream>
using namespace std;

// forward declaration
class B;
class A {
    private:
      int numA;
    public:
      A(): numA(12) { }
      // friend function declaration
      friend int add(A, B);
};

class B {
    private:
       int numB;
    public:
       B(): numB(1) { }
       // friend function declaration
       friend int add(A , B);
};

// Function add() is the friend function of classes A and B
// that accesses the member variables numA and numB
int add(A objectA, B objectB)
{
   return (objectA.numA + objectB.numB);
}

int main()
{
    A objectA;
    B objectB;
    cout<<"Sum: "<< add(objectA, objectB);
    return 0;
}

Output

Sum: 13

In this program, classes A and B have declared add() as a friend function. Thus, this function can access private data of both class.

Here, add() function adds the private data numA and numB of two objects objectA and objectB, and returns it to the main function.

To make this program work properly, a forward declaration of a class class B should be made as shown in the above example.

This is because class B is referenced within the class A using code: friend int add(A , B);.


friend Class in C++ Programming

Similarly, like a friend function, a class can also be made a friend of another class using keyword friend. For example:

... .. ...
class B;
class A
{
   // class B is a friend class of class A
   friend class B;
   ... .. ...
}

class B
{
   ... .. ...
}

When a class is made a friend class, all the member functions of that class becomes friend functions.

In this program, all member functions of class B will be friend functions of class A. Thus, any member function of class B can access the private and protected data of class A. But, member functions of class A cannot access the data of class B.

Remember, friend relation in C++ is only granted, not taken.

C++ Virtual Function

In this article, you will learn about virtual function and where to use it. Also, you will learn about pure virtual function and abstract class.

A virtual function is a member function in the base class that you expect to redefine in derived classes.

Before going into detail, let’s build an intuition on why virtual functions are needed in the first place.


An Example to Begin With

Let us assume, we are working on a game (weapons specifically).

We created the Weapon class and derived two classes Bomb and Gun to load features of respective weapons.

#include <iostream>
using namespace std;

class Weapon {
   public:
   void loadFeatures() { cout << "Loading weapon features.\n"; }
};

class Bomb : public Weapon {
   public:
   void loadFeatures() { cout << "Loading bomb features.\n"; }
};

class Gun : public Weapon {
   public:
   void loadFeatures() { cout << "Loading gun features.\n"; }
};

int main() {
   Weapon *w = new Weapon;
   Bomb *b = new Bomb;
   Gun *g = new Gun;

   w->loadFeatures();
   b->loadFeatures();
   g->loadFeatures();

   return 0;
}

Output

Loading weapon features.
Loading bomb features.
Loading gun features.

We defined three pointer objects wb and g of classes WeaponBomb and Gun respectively. And, we called loadFeatures() member function of each objects using:

w->loadFeatures();
b->loadFeatures();
g->loadFeatures();

Works perfectly!

However, our game project started getting bigger and bigger. And, we decided to create a separate Loader class to load weapon features.

This Loader class loads additional features of a weapon depending on which weapon is selected.

class Loader
{
   public:
     void loadFeatures(Weapon *weapon)
     {
        weapon->features();
     }     
};

The loadFeatures() loads the feature of a specific weapon.


Let’s try to implement our Loader class

#include <iostream>
using namespace std;
class Weapon {
   public:
   Weapon() { cout << "Loading weapon features.\n"; }

   void features() { cout << "Loading weapon features.\n"; }
};
class Bomb : public Weapon {
   public:
   void features() {
      this->Weapon::features();
      cout << "Loading bomb features.\n";
   }
};
class Gun : public Weapon {
   public:
   void features() {
      this->Weapon::features();
      cout << "Loading gun features.\n";
   }
};
class Loader {
   public:
   void loadFeatures(Weapon *weapon) {
      weapon->features();
   }
};
int main() {
   Loader *l = new Loader;
   Weapon *w;
   Bomb b;
   Gun g;
   w = &b;
   l->loadFeatures(w);
   w = &g;
   l->loadFeatures(w);
   return 0;
}

Output

Loading weapon features.
Loading weapon features. 
Loading weapon features.
Loading weapon features. 

Our implementation seemed correct. However, weapon features were loaded 4 times. Why?

Initially, the Weapon object w is pointing to the b object (of Bomb) class. And, we tried to load the features of Bomb object by passing it to loadFeatures() function using l object to pointer (of Loader class).

Similarly, we tried to load the features of Gun object.

However, the loadFeatures() function of the Loader class takes pointer to object of a Weapon class as an argument:

void loadFeatures(Weapon *weapon)

That’s the reason weapon features are loaded 4 times. To solve this issue, we need to make function of base class (Weapon class) virtual using virtual keyword.

class Weapon
{
    public:
      virtual void features()
         { cout << "Loading weapon features.\n"; }
};


Example: Using Virtual Function to Solve the Problem

#include <iostream>
using namespace std;

class Weapon {
   public:
   virtual void features() { cout << "Loading weapon features.\n"; }
};

class Bomb : public Weapon {
   public:
   void features() {
      this->Weapon::features();
      cout << "Loading bomb features.\n";
   }
};

class Gun : public Weapon {
   public:
   void features() {
      this->Weapon::features();
      cout << "Loading gun features.\n";
   }
};

class Loader {
   public:
   void loadFeatures(Weapon *weapon) {
      weapon->features();
   }
};

int main() {
   Loader *l = new Loader;
   Weapon *w;
   Bomb b;
   Gun g;

   w = &b;
   l->loadFeatures(w);

   w = &g;
   l->loadFeatures(w);

   return 0;
}

Output

Loading weapon features.
Loading bomb features.
Loading weapon features. 
Loading gun features.

Also, notice that, the l->loadFeatures(w) function calls the function of different classes depending upon what l object is pointing.

Using virtual function made our code not only clearer but flexible too.

In the above program, weapon features is printed twice. We encourage you to add additional code on the above program to load weapon features only once.

If we want to add another weapon (let’s say knife), we can easily add and load features of it. How?

class Knife : public Weapon {
   public:
   void features() {
      this-<Weapon::features();
      cout >> "Loading knife features.\n";
   }
};

And, in the main() function.

Knife k; 
w = &k; 
l->loadFeatures(w);

It’s worth noticing that we didn’t change anything in the Loader class to load features of knife.


C++ Abstract class and Pure virtual Function

The goal of object-oriented programming is to divide a complex problem into small sets. This helps understand and work with problem in an efficient way.

Sometimes, it’s desirable to use inheritance just for the case of better visualization of the problem.

In C++, you can create an abstract class that cannot be instantiated (you cannot create object of that class). However, you can derive a class from it and instantiate object of the derived class.

Abstract classes are the base class which cannot be instantiated.

A class containing pure virtual function is known as abstract class.


Pure Virtual Function

A virtual function whose declaration ends with =0 is called a pure virtual function. For example,

class Weapon
{
    public:
      virtual void features() = 0;
};

Here, the pure virtual function is

virtual void features() = 0

And, the class Weapon is an abstract class.


Example: Abstract Class and Pure Virtual Function

#include <iostream>
using namespace std;

// Abstract class
class Shape                   
{
    protected:
       float l;
    public:
       void getData()       
       {
           cin >> l;
       }
       
       // virtual Function
       virtual float calculateArea() = 0;
};

class Square : public Shape
{
    public:
       float calculateArea()
       {   return l*l;  }
};

class Circle : public Shape
{
    public:
       float calculateArea()
       { return 3.14*l*l; }
};

int main()
{
    Square s;
    Circle c;

    cout << "Enter length to calculate the area of a square: ";
    s.getData();
    cout<<"Area of square: " << s.calculateArea();
    cout<<"\nEnter radius to calculate the area of a circle: ";
    c.getData();
    cout << "Area of circle: " << c.calculateArea();

    return 0;
}

Output

Enter length to calculate the area of a square: 4
Area of square: 16
Enter radius to calculate the area of a circle: 5
Area of circle: 78.5

In this program, pure virtual function virtual float area() = 0; is defined inside the Shape class.

One important thing to note is that, you should override the pure virtual function of the base class in the derived class. If you fail the override it, the derived class will become an abstract class as well.

C++ Multiple, Multilevel and Hierarchical Inheritance

In this article, you will learn about different models of inheritance in C++ programming: Multiple, Multilevel and Hierarchical inheritance with examples.

Inheritance is one of the core feature of an object-oriented programming language. It allows software developers to derive a new class from the existing class. The derived class inherits the features of the base class (existing class).

There are various models of inheritance in C++ programming.


C++ Multilevel Inheritance

In C++ programming, not only you can derive a class from the base class but you can also derive a class from the derived class. This form of inheritance is known as multilevel inheritance.

class A
{ 
... .. ... 
};
class B: public A
{
... .. ...
};
class C: public B
{
... ... ...
};

Here, class B is derived from the base class A and the class C is derived from the derived class B.


Example 1: C++ Multilevel Inheritance

#include <iostream>
using namespace std;

class A
{
    public:
      void display()
      {
          cout<<"Base class content.";
      }
};

class B : public A
{

};

class C : public B
{
 
};

int main()
{
    C obj;
    obj.display();
    return 0;
}

Output

Base class content.

In this program, class C is derived from class B (which is derived from base class A).

The obj object of class C is defined in the main() function.

When the display() function is called, display() in class A is executed. It’s because there is no display() function in class C and class B.

The compiler first looks for the display() function in class C. Since the function doesn’t exist there, it looks for the function in class B (as C is derived from B).

The function also doesn’t exist in class B, so the compiler looks for it in class A (as B is derived from A).

If display() function exists in C, the compiler overrides display() of class A (because of member function overriding).


C++ Multiple Inheritance

In C++ programming, a class can be derived from more than one parents. For example: A class Bat is derived from base classes Mammal and WingedAnimal. It makes sense because bat is a mammal as well as a winged animal.

C++ Multiple Inheritance Example

Example 2: Multiple Inheritance in C++ Programming

#include <iostream>
using namespace std;

class Mammal {
  public:
    Mammal()
    {
      cout << "Mammals can give direct birth." << endl;
    }
};

class WingedAnimal {
  public:
    WingedAnimal()
    {
      cout << "Winged animal can flap." << endl;
    }
};

class Bat: public Mammal, public WingedAnimal {

};

int main()
{
    Bat b1;
    return 0;
}

Output

Mammals can give direct birth.
Winged animal can flap.

Ambiguity in Multiple Inheritance

The most obvious problem with multiple inheritance occurs during function overriding.

Suppose, two base classes have a same function which is not overridden in derived class.

If you try to call the function using the object of the derived class, compiler shows error. It’s because compiler doesn’t know which function to call. For example,

class base1
{
  public:
     void someFunction( )
     { .... ... .... }  
};
class base2
{
    void someFunction( )
     { .... ... .... } 
};
class derived : public base1, public base2
{
    
};

int main()
{
    derived obj;

    obj.someFunction() // Error!  
}


This problem can be solved using scope resolution function to specify which function to class either base1or base2

int main()
{
    obj.base1::someFunction( );  // Function of base1 class is called
    obj.base2::someFunction();   // Function of base2 class is called.
}

C++ Hierarchical Inheritance

If more than one class is inherited from the base class, it’s known as hierarchical inheritance. In hierarchical inheritance, all features that are common in child classes are included in the base class.

For example: Physics, Chemistry, Biology are derived from Science class.


Syntax of Hierarchical Inheritance

class base_class {
     ... .. ...
}

class first_derived_class: public base_class {
     ... .. ...
}

class second_derived_class: public base_class {
     ... .. ...
}

class third_derived_class: public base_class {
     ... .. ...
}

Public, Protected and Private Inheritance in C++ Programming

In this article, you’ll learn to use public, protected and private inheritance in C++. You’ll learn where and how it is used, with examples.

You can declare a derived class from a base class with different access control, i.e., public inheritance, protected inheritance or private inheritance.

#include <iostream>
using namespace std;

class base
{
.... ... ....
};

class derived : access_specifier base
{
.... ... ....
};

Note: Either publicprotected or private keyword is used in place of access_specifier term used in the above code.

Example of public, protected and private inheritance in C++

class base 
{
	public:
		int x;
	protected:
		int y;
	private:
		int z;
};

class publicDerived: public base
{
	// x is public
	// y is protected
	// z is not accessible from publicDerived
};

class protectedDerived: protected base
{
	// x is protected
	// y is protected
	// z is not accessible from protectedDerived
};

class privateDerived: private base
{
	// x is private
	// y is private
	// z is not accessible from privateDerived
}

In the above example, we observe the following things:

  • base has three member variables: x, y and z which are publicprotected and private member respectively.
  • publicDerived inherits variables x and y as public and protected. z is not inherited as it is a private member variable of base.
  • protectedDerived inherits variables x and y. Both variables become protected. z is not inherited
    If we derive a class derivedFromProtectedDerived from protectedDerived, variables x and y are also inherited to the derived class.
  • privateDerived inherits variables x and y. Both variables become private. z is not inherited
    If we derive a class derivedFromPrivateDerived from privateDerived, variables x and y are not inherited because they are private variables of privateDerived.

Accessibility in Public Inheritance

Accessibilityprivate variablesprotected variablespublic variables
Accessible from own class?yesyesyes
Accessible from derived class?noyesyes
Accessible from 2nd derived class?noyesyes

Accessibility in Protected Inheritance

Accessibilityprivate variablesprotected variablespublic variables
Accessible from own class?yesyesyes
Accessible from derived class?noyesyes
(inherited as protected variables)
Accessible from 2nd derived class?noyesyes

Accessibility in Private Inheritance

Accessibilityprivate variablesprotected variablespublic variables
Accessible from own class?yesyesyes
Accessible from derived class?noyes
(inherited as private variables)
yes
(inherited as private variables)
Accessible from 2nd derived class?nonono

C++ Inheritance

In this article, you’ll learn everything about inheritance in C++. More specifically, what is inheritance and different ways to implement it with examples.

Inheritance is one of the key features of Object-oriented programming in C++. It allows user to create a new class (derived class) from an existing class(base class).

The derived class inherits all the features from the base class and can have additional features of its own.


Why inheritance should be used?

Suppose, in your game, you want three characters – a maths teacher, a footballer and a businessman.

Since, all of the characters are persons, they can walk and talk. However, they also have some special skills. A maths teacher can teach maths, a footballer can play football and a businessman can run a business.

You can individually create three classes who can walk, talk and perform their special skill as shown in the figure below.

Solving a problem without inheritance in C++

In each of the classes, you would be copying the same code for walk and talk for each character.

If you want to add a new feature – eat, you need to implement the same code for each character. This can easily become error prone (when copying) and duplicate codes.

It’d be a lot easier if we had a Person class with basic features like talk, walk, eat, sleep, and add special skills to those features as per our characters. This is done using inheritance.

Solving a problem with inheritance in C++

Using inheritance, now you don’t implement the same code for walk and talk for each class. You just need to inherit them.

So, for Maths teacher (derived class), you inherit all features of a Person (base class) and add a new feature TeachMaths. Likewise, for a footballer, you inherit all the features of a Person and add a new feature PlayFootball and so on.

This makes your code cleaner, understandable and extendable.

It is important to remember: When working with inheritance, each derived class should satisfy the condition whether it “is a” base class or not. In the example above, Maths teacher is a Person, Footballer is a Person. You cannot have: Businessman is a Business.


Implementation of Inheritance in C++ Programming

class Person 
{
  ... .. ...
};

class MathsTeacher : public Person 
{
  ... .. ...
};

class Footballer : public Person
{
  .... .. ...
};

In the above example, class Person is a base class and classes MathsTeacher and Footballer are the derived from Person.

The derived class appears with the declaration of a class followed by a colon, the keyword public and the name of base class from which it is derived.

Since, MathsTeacher and Footballer are derived from Person, all data member and member function of Person can be accessible from them.


Example: Inheritance in C++ Programming

Create game characters using the concept of inheritance.

#include <iostream>
using namespace std;

class Person
{
     public:
        string profession;
        int age;

        Person(): profession("unemployed"), age(16) { }
        void display()
        {
             cout << "My profession is: " << profession << endl;
             cout << "My age is: " << age << endl;
             walk();
             talk();
        }
        void walk() { cout << "I can walk." << endl; }
        void talk() { cout << "I can talk." << endl; }
};

// MathsTeacher class is derived from base class Person.
class MathsTeacher : public Person
{
    public:
       void teachMaths() { cout << "I can teach Maths." << endl; }
};

// Footballer class is derived from base class Person.
class Footballer : public Person
{
    public:
       void playFootball() { cout << "I can play Football." << endl; }
};

int main()
{
     MathsTeacher teacher;
     teacher.profession = "Teacher";
     teacher.age = 23;
     teacher.display();
     teacher.teachMaths();

     Footballer footballer;
     footballer.profession = "Footballer";
     footballer.age = 19;
     footballer.display();
     footballer.playFootball();

     return 0;
}

Output

My profession is: Teacher
My age is: 23
I can walk.
I can talk.
I can teach Maths.
My profession is: Footballer
My age is: 19
I can walk.
I can talk.
I can play Football.

In this program, Person is a base class, while MathsTeacher and Footballer are derived from Person.

Person class has two data members – profession and age. It also has two member functions – walk() and talk().

Both MathsTeacher and Footballer can access all data members and member functions of Person.

However, MathsTeacher and Footballer have their own member functions as well: teachMaths() and playFootball() respectively. These functions are only accessed by their own class.

In the main() function, a new MathsTeacher object teacher is created.

Since, it has access to Person‘s data members, profession and age of teacher is set. This data is displayed using the display() function defined in the Person class. Also, the teachMaths() function is called, defined in the MathsTeacher class.

Likewise, a new Footballer object footballer is also created. It has access to Person‘s data members as well, which is displayed by invoking the display() function. The playFootball() function only accessible by the footballer is called then after.


Access specifiers in Inheritance

When creating a derived class from a base class, you can use different access specifiers to inherit the data members of the base class.

These can be public, protected or private.

In the above example, the base class Person has been inherited public-ly by MathsTeacher and Footballer.

Learn more about Public, Protected and Private Inheritance in C++.


Member Function Overriding in Inheritance

Suppose, base class and derived class have member functions with same name and arguments.

If you create an object of the derived class and try to access that member function, the member function in derived class is only invoked.

The member function of derived class overrides the member function of base class.

Learn more about Function overriding in C++.

C++ Call by Reference: Using pointers

In this article, you’ll learn to pass pointers as an argument to the function, and use it efficiently in your program.

In C++ Functions article, you learned about passing arguments to a function. This method used is called passing by value because the actual value is passed.

However, there is another way of passing an argument to a function where where the actual value of the argument is not passed. Instead, only the reference to that value is passed.


Example 1: Passing by reference without pointers

#include <iostream>
using namespace std;

// Function prototype
void swap(int&, int&);

int main()
{
    int a = 1, b = 2;
    cout << "Before swapping" << endl;
    cout << "a = " << a << endl;
    cout << "b = " << b << endl;

    swap(a, b);

    cout << "\nAfter swapping" << endl;
    cout << "a = " << a << endl;
    cout << "b = " << b << endl;

    return 0;
}

void swap(int& n1, int& n2) {
    int temp;
    temp = n1;
    n1 = n2;
    n2 = temp;
}

Output

Before swapping
a = 1
b = 2

After swapping
a = 2
b = 1

In main(), two integer variables a and b are defined. And those integers are passed to a function swap() by reference.

Compiler can identify this is pass by reference because function definition is void swap(int& n1, int& n2) (notice the & sign after data type).

Only the reference (address) of the variables a and b are received in the swap() function and swapping takes place in the original address of the variables.

In the swap() function, n1 and n2 are formal arguments which are actually same as variables a and b respectively.

There is another way of doing this same exact task using pointers.


Example 2: Passing by reference using pointers

#include <iostream>
using namespace std;

// Function prototype
void swap(int*, int*);

int main()
{
    int a = 1, b = 2;
    cout << "Before swapping" << endl;
    cout << "a = " << a << endl;
    cout << "b = " << b << endl;

    swap(&a, &b);

    cout << "\nAfter swapping" << endl;
    cout << "a = " << a << endl;
    cout << "b = " << b << endl;
    return 0;
}

void swap(int* n1, int* n2) {
    int temp;
    temp = *n1;
    *n1 = *n2;
    *n2 = temp;
}

The output of this example is same as before.

In this case, the address of variable is passed during function call rather than the variable itself.

swap(&a, &b); // &a is address of a and &b is address of b

Since the address is passed instead of value, dereference operator must be used to access the value stored in that address.

void swap(int* n1, int* n2) { 
 ... .. ...
}

The *n1 and *n2 gives the value stored at address n1 and n2 respectively.

Since n1 contains the address of a, anything done to *n1 changes the value of a in main() function as well. Similarly, b will have same value as *n2.

C++ Pointers and Arrays

In this article, you’ll learn about the relation between arrays and pointers, and use them efficiently in your program.

Pointers are the variables that hold address. Not only can pointers store address of a single variable, it can also store address of cells of an array.

Consider this example:

int* ptr;
int a[5];
ptr = &a[2];  // &a[2] is the address of third element of a[5].
Pointer pointing to an array cell

Suppose, pointer needs to point to the fourth element of an array, that is, hold address of fourth array element in above case.

Since ptr points to the third element in the above example, ptr + 1 will point to the fourth element.

You may think, ptr + 1 gives you the address of next byte to the ptr. But it’s not correct.

This is because pointer ptr is a pointer to an int and size of int is fixed for a operating system (size of int is 4 byte of 64-bit operating system). Hence, the address between ptr and ptr + 1 differs by 4 bytes.

If pointer ptr was pointer to char then, the address between ptr and ptr + 1 would have differed by 1 byte since size of a character is 1 byte.


Example 1: C++ Pointers and Arrays

C++ Program to display address of elements of an array using both array and pointers

#include <iostream>
using namespace std;

int main()
{
    float arr[5];
    float *ptr;
    
    cout << "Displaying address using arrays: " << endl;
    for (int i = 0; i < 5; ++i)
    {
        cout << "&arr[" << i << "] = " << &arr[i] << endl;
    }

    // ptr = &arr[0]
    ptr = arr;

    cout<<"\nDisplaying address using pointers: "<< endl;
    for (int i = 0; i < 5; ++i)
    {
        cout << "ptr + " << i << " = "<< ptr + i << endl;
    }

    return 0;
}

Output

Displaying address using arrays: 
&arr[0] = 0x7fff5fbff880
&arr[1] = 0x7fff5fbff884
&arr[2] = 0x7fff5fbff888
&arr[3] = 0x7fff5fbff88c
&arr[4] = 0x7fff5fbff890

Displaying address using pointers: 
ptr + 0 = 0x7fff5fbff880
ptr + 1 = 0x7fff5fbff884
ptr + 2 = 0x7fff5fbff888
ptr + 3 = 0x7fff5fbff88c
ptr + 4 = 0x7fff5fbff890

In the above program, a different pointer ptr is used for displaying the address of array elements arr.

But, array elements can be accessed using pointer notation by using same array name arr. For example:

int arr[3];

&arr[0] is equivalent to arr
&arr[1] is equivalent to arr + 1
&arr[2] is equivalen to arr + 2

Example 2: Pointer and Arrays

C++ Program to display address of array elements using pointer notation.

#include <iostream>
using namespace std;

int main() {
    float arr[5];
    
    cout<<"Displaying address using pointers notation: "<< endl;
    for (int i = 0; i < 5; ++i) {
        cout << arr + i <<endl;
    }

    return 0;
}

Output

Displaying address using pointers notation: 
0x7fff5fbff8a0
0x7fff5fbff8a4
0x7fff5fbff8a8
0x7fff5fbff8ac
0x7fff5fbff8b0

You know that, pointer ptr holds the address and expression *ptr gives the value stored in the address.

Similarly, you can get the value stored in the pointer ptr + 1 using *(ptr + 1).

Consider this code below:

int ptr[5] = {3, 4, 5, 5, 3};
  • &ptr[0] is equal to ptr and *ptr is equal to ptr[0]
  • &ptr[1] is equal to ptr + 1 and *(ptr + 1) is equal to ptr[1]
  • &ptr[2] is equal to ptr + 2 and *(ptr + 2) is equal to ptr[2]
  • &ptr[i] is equal to ptr + i and *(ptr + i) is equal to ptr[i]

Example 3: C++ Pointer and Array

C++ Program to insert and display data entered by using pointer notation.

#include <iostream>
using namespace std;

int main() {
    float arr[5];
    
   // Inserting data using pointer notation
    cout << "Enter 5 numbers: ";
    for (int i = 0; i < 5; ++i) {
        cin >> *(arr + i) ;
    }

    // Displaying data using pointer notation
    cout << "Displaying data: " << endl;
    for (int i = 0; i < 5; ++i) {
        cout << *(arr + i) << endl ;
    }

    return 0;
}

Output

Enter 5 numbers: 2.5
3.5
4.5
5
2
Displaying data: 
2.5
3.5
4.5
5
2

C++ Operator Overloading

In C++, it’s possible to change the way operator works (for user-defined types). In this article, you will learn to implement operator overloading feature.

The meaning of an operator is always same for variable of basic types like: int, float, double etc. For example: To add two integers, + operator is used.

However, for user-defined types (like: objects), you can redefine the way operator works. For example:

If there are two objects of a class that contains string as its data members. You can redefine the meaning of + operator and use it to concatenate those strings.

This feature in C++ programming that allows programmer to redefine the meaning of an operator (when they operate on class objects) is known as operator overloading.


Why is operator overloading used?

You can write any C++ program without the knowledge of operator overloading. However, operator operating are profoundly used by programmers to make program intuitive. For example,

You can replace the code like:

calculation = add(multiply(a, b),divide(a, b));

to

calculation = (a*b)+(a/b);

How to overload operators in C++ programming?

To overload an operator, a special operator function is defined inside the class as:

class className
{
    ... .. ...
    public
       returnType operator symbol (arguments)
       {
           ... .. ...
       } 
    ... .. ...
};
  • Here, returnType is the return type of the function.
  • The returnType of the function is followed by operator keyword.
  • Symbol is the operator symbol you want to overload. Like: +, <, -, ++
  • You can pass arguments to the operator function in similar way as functions.

Example: Operator overloading in C++ Programming

#include <iostream>
using namespace std;

class Test
{
   private:
      int count;

   public:
       Test(): count(5){}

       void operator ++() 
       { 
          count = count+1; 
       }
       void Display() { cout<<"Count: "<<count; }
};

int main()
{
    Test t;
    // this calls "function void operator ++()" function
    ++t;    
    t.Display();
    return 0;
}

Output

Count: 6

This function is called when ++ operator operates on the object of Test class (object t in this case).

In the program,void operator ++ () operator function is defined (inside Test class).

This function increments the value of count by 1 for t object.


Things to remember

  1. Operator overloading allows you to redefine the way operator works for user-defined types only (objects, structures). It cannot be used for built-in types (int, float, char etc.).
  2. Two operators = and & are already overloaded by default in C++. For example: To copy objects of same class, you can directly use = operator. You do not need to create an operator function.
  3. Operator overloading cannot change the precedence and associatively of operators. However, if you want to change the order of evaluation, parenthesis should be used.
  4. There are 4 operators that cannot be overloaded in C++. They are :: (scope resolution), . (member selection), .* (member selection through pointer to function) and ?: (ternary operator).

Following best practices while using operator overloading

Operator overloading allows you to define the way operator works (the way you want).

In the above example, ++ operator operates on object to increase the value of data member count by 1.

void operator ++() 
    { 
        count = count+1; 
    }

However, if you use the following code. It decreases the value of count by 100 when ++ operator is used.

void operator ++() 
    { 
        count = count-100; 
    }

This may be technically correct. But, this code is confusing and, difficult to understand and debug.

It’s your job as a programmer to use operator overloading properly and in consistent way.


In the above example, the value of count increases by 1 when ++ operator is used. However, this program is incomplete in sense that you cannot use code like:

t1 = ++t

It is because the return type of the operator function is void.

C++ Pointers

In this article, you’ll learn everything about pointers. You’ll learn how values are stored in the computer and how to access them using pointers.

Pointers are powerful features of C++ that differentiates it from other programming languages like Java and Python.

Pointers are used in C++ program to access the memory and manipulate the address.


Address in C++

To understand pointers, you should first know how data is stored on the computer.

Each variable you create in your program is assigned a location in the computer’s memory. The value the variable stores is actually stored in the location assigned.

To know where the data is stored, C++ has an & operator. The & (reference) operator gives you the address occupied by a variable.

If var is a variable then, &var gives the address of that variable.

Example 1: Address in C++

#include <iostream>
using namespace std;

int main()
{
    int var1 = 3;
    int var2 = 24;
    int var3 = 17;
    cout << &var1 << endl;
    cout << &var2 << endl;
    cout << &var3 << endl;
}

Output

0x7fff5fbff8ac
0x7fff5fbff8a8
0x7fff5fbff8a4

Note: You may not get the same result on your system.

The 0x in the beginning represents the address is in hexadecimal form.

Notice that first address differs from second by 4-bytes and second address differs from third by 4-bytes.

This is because the size of integer (variable of type int) is 4 bytes in 64-bit system.


Pointers Variables

C++ gives you the power to manipulate the data in the computer’s memory directly. You can assign and de-assign any space in the memory as you wish. This is done using Pointer variables.

Pointers variables are variables that points to a specific address in the memory pointed by another variable.


How to declare a pointer?

int *p;
      OR,
int* p;

The statement above defines a pointer variable p. It holds the memory address

The asterisk is a dereference operator which means pointer to.

Here, pointer p is a pointer to int, i.e., it is pointing to an integer value in the memory address.


Reference operator (&) and Deference operator (*)

Reference operator (&) as discussed above gives the address of a variable.

To get the value stored in the memory address, we use the dereference operator (*).

For example: If a number variable is stored in the memory address 0x123, and it contains a value 5.

The reference (&) operator gives the value 0x123, while the dereference (*) operator gives the value 5.

Note: The (*) sign used in the declaration of C++ pointer is not the dereference pointer. It is just a similar notation that creates a pointer.


Example 2: C++ Pointers

C++ Program to demonstrate the working of pointer.

#include <iostream>
using namespace std;
int main() {
    int *pc, c;
    
    c = 5;
    cout << "Address of c (&c): " << &c << endl;
    cout << "Value of c (c): " << c << endl << endl;

    pc = &c;    // Pointer pc holds the memory address of variable c
    cout << "Address that pointer pc holds (pc): "<< pc << endl;
    cout << "Content of the address pointer pc holds (*pc): " << *pc << endl << endl;
    
    c = 11;    // The content inside memory address &c is changed from 5 to 11.
    cout << "Address pointer pc holds (pc): " << pc << endl;
    cout << "Content of the address pointer pc holds (*pc): " << *pc << endl << endl;

    *pc = 2; 
    cout << "Address of c (&c): " << &c << endl;
    cout << "Value of c (c): " << c << endl << endl;

    return 0;
}

Output

Address of c (&c): 0x7fff5fbff80c
Value of c (c): 5

Address that pointer pc holds (pc): 0x7fff5fbff80c
Content of the address pointer pc holds (*pc): 5

Address pointer pc holds (pc): 0x7fff5fbff80c
Content of the address pointer pc holds (*pc): 11

Address of c (&c): 0x7fff5fbff80c
Value of c (c): 2
Working of pointer in C++ programming

Explanation of program

  • When c = 5; the value 5 is stored in the address of variable c – 0x7fff5fbff8c.
  • When pc = &c; the pointer pc holds the address of c – 0x7fff5fbff8c, and the expression (dereference operator) *pc outputs the value stored in that address, 5.
  • When c = 11; since the address pointer pc holds is the same as c – 0x7fff5fbff8c, change in the value of c is also reflected when the expression *pc is executed, which now outputs 11.
  • When *pc = 2; it changes the content of the address stored by pc – 0x7fff5fbff8c. This is changed from 11 to 2. So, when we print the value of c, the value is 2 as well.

Common mistakes when working with pointers

Suppose, you want pointer pc to point to the address of c. Then,

int c, *pc;
pc=c;  /* Wrong! pc is address whereas, c is not an address. */
*pc=&c; /* Wrong! *pc is the value pointed by address whereas, %amp;c is an address. */
pc=&c; /* Correct! pc is an address and, %amp;pc is also an address. */
*pc=c; /* Correct! *pc is the value pointed by address and, c is also a value. */

In both cases, pointer pc is not pointing to the address of c.

How to pass and return object from a function in C++?

In this article, you will learn to pass objects to a function and return object from a function in C++ programming.

In C++ programming, objects can be passed to a function in a similar way as structures.


How to pass objects to a function?

Pass Object to a function in C++

Example 1: Pass Objects to Function

C++ program to add two complex numbers by passing objects to a function.

#include <iostream>
using namespace std;

class Complex
{
    private:
       int real;
       int imag;
    public:
       Complex(): real(0), imag(0) { }
       void readData()
        {
           cout << "Enter real and imaginary number respectively:"<<endl;
           cin >> real >> imag;
        }
        void addComplexNumbers(Complex comp1, Complex comp2)
        {
           // real represents the real data of object c3 because this function is called using code c3.add(c1,c2);
            real=comp1.real+comp2.real;

             // imag represents the imag data of object c3 because this function is called using code c3.add(c1,c2);
            imag=comp1.imag+comp2.imag;
        }

        void displaySum()
        {
            cout << "Sum = " << real<< "+" << imag << "i";
        }
};
int main()
{
    Complex c1,c2,c3;

    c1.readData();
    c2.readData();

    c3.addComplexNumbers(c1, c2);
    c3.displaySum();

    return 0;
}

Output

Enter real and imaginary number respectively:
2
4
Enter real and imaginary number respectively:
-3
4
Sum = -1+8i

How to return an object from the function?

In C++ programming, object can be returned from a function in a similar way as structures.

Return object from a function in C++

Example 2: Pass and Return Object from the Function

In this program, the sum of complex numbers (object) is returned to the main() function and displayed.

#include <iostream>
using namespace std;
class Complex
{
    private:
       int real;
       int imag;
    public:
       Complex(): real(0), imag(0) { }
       void readData()
        {
           cout << "Enter real and imaginary number respectively:"<<endl;
           cin >> real >> imag;
        }
        Complex addComplexNumbers(Complex comp2)
        {
            Complex temp;

            // real represents the real data of object c3 because this function is called using code c3.add(c1,c2);
            temp.real = real+comp2.real;

            // imag represents the imag data of object c3 because this function is called using code c3.add(c1,c2);
            temp.imag = imag+comp2.imag;
            return temp;
        }
        void displayData()
        {
            cout << "Sum = " << real << "+" << imag << "i";
        }
};

int main()
{
    Complex c1, c2, c3;

    c1.readData();
    c2.readData();

    c3 = c1.addComplexNumbers(c2);

    c3.displayData();
    
    return 0;
}