UNIT-1
Basics of Object-Oriented Programming
The C++ language is an object-oriented programming language & is a combination of both low-level & high-level language – a Middle-Level Language. The programming language was created, designed & developed by a Danish Computer Scientist – Bjarne Stroustrup at Bell Telephone Laboratories (now known as Nokia Bell Labs) in Murray Hill, New Jersey. As he wanted a flexible & a dynamic language which was similar to C with all its features, but with additionality of active type checking, basic inheritance, default functioning argument, classes, inlining, etc. and hence C with Classes (C++) was launched.
C++ was initially known as “C with classes, ” and was renamed C++ in 1983. ++ is shorthand for adding one to variety in programming; therefore C++ roughly means that “one higher than C.”
- The trace of the programming language C++ can be done back to 1979 when Bjarne Stroustrup was doing some development for this thesis for PhD. One in all the words Stroustrup had the chance to figure with, was a language referred to as Simula, that because the name implies, could be a language primarily designed for simulations. The Simula sixty-seven language – that was the variant that Stroustrup worked with is considered the primary language to support the object-oriented programming paradigm. Stroustrup found that this paradigm was helpful for package development; but, the Simula language was way too slow for practice & practical use.
- Shortly subsequently, he began work on “C with Classes“, because what the name implies was meant to be a superset of the C language. His main dream was to get his advanced object-oriented programming, created by him, into the C language, which was during his era was still the programming language that was widely respected for its movability, portability & compactness, by not sacrificing the speed or the low-level practicality. His programming-language enclosed inlining, basic inheritance, default function arguments, categories, and reliable sort was checking additionally to all or any the options of the C language.
- The first C with categories compiler was referred to as Cfront, that got derived from a C compiler referred to as CPre. It had been a program designed to translate C with categories code to universal C. A rather attention-grabbing purpose value noting is that Cfront was written mostly in C with classes, creating it a self-hosting compiler (a compiler which will compile itself). Cfront would later be abandoned in 1993 when it became troublesome to integrate new options into it, mainly C++ exceptions. Even so, Cfront created a significant impact on the implementations of future compilers and also the operating system UNIX.
- In 1983, the name of the language got modified from C with categories to C++. The ++ operator within the C language is the associate operator for incrementing a variable, which provides some insight into however Stroustrup regarded the programming language. Several new options got additional around this point, the foremost notable of that area unit virtual functions, perform overloading, references with the const keyword, and single-line comments by using the two forward slashes (which may be a feature taken from the language BCPL).
- In 1985, Stroustrup’s relation to the language entitled The C++ programming language was printed and got released. That very same year, C++ got enforced as an advertisement product and hence starting of it as a commercial element. The programming language wasn’t formally standardized, nevertheless creating the book an essential reference. The programming language was updated once more in 1989 to incorporate protected and static members, still as an associate inheritance from many categories & classes.
- In 1990, The Annotated C++ manual, which was a reference got released all over. In 1990 only, in the same & identical year, Borland’s Turbo C++ compiler would also be commercially discharged as an advertisement product. Turbo C++ additional an excessiveness of other libraries which might have a substantial impact on C++’s development. Though Turbo C++’s last stable unharness was in 2006, the compiler continues to get widely used.
- In 1998, the C++ customary advisory & standards committee printed the first international standard for C++ ISO/IEC 14882:1998, which might be informally called C++98. The Annotated C++ manual was aforementioned to be a significant influence within the development of the quality. The quality template library (also known as the Standard Template Library) that began its intellectual construction in 1979 got additionally enclosed in it. In 2003, the committee well-versed multiple issues that were according with their 1998 customary and revised it consequently. The modified language got dubbed as C++03.
- In 2005, the same committee of C++ discharged a technical report (called as TR1) particularization varied options they were aiming to boost the newest C++ standard. The new rule was informally dubbed C++0x because it was expected to be discharged someday before the tip of the first decade. Ironically, however, the new customary wasn’t fulfilled until mid-2011. Many technical reports were discharged up till then, and a few compilers began adding experimental support for the new options and features.
- In mid-2011, the new C++ customary (dubbed C++11) got finished. The Boost library project created a substantial impact on the new rule, and a few of the new modules were derived directly from the corresponding Boost libraries. A number of the new options that got included were:
- New for loop syntax providing practicality just like foreach loops in specific different languages
- Customary threading library (which up till 2011 each C and C++ were lacking)
- Variadic templates
- Automotive vehicle (AUTO) keyword
- New instrumentation categories & classes
- New C++ time library, atomics support
- Comprehensive organization library
- Regular expression support
- Higher support for unions and array-initialization lists
- C++ 17 is the latest version of C++. A newer & advanced version of C++ is being released, i.e. C++20.
- C++ is still the third most popular programming language according to the TIOBE Index’s latest study of 2019, behind Java & C, by knocking out Python. All credits for this go to the newly released C++11 version, which according to the users made it much robust, safer, easier simpler, and more expressive.
Bjarne Stroustrup has created excellent work with C++. C could be a low-level programing language, and so, it does not have any classes. It does not contain several options which will create programming more well-off, however, is that the quickest language (assembly is more rapid; however, programming in construction isn’t one thing you’d consider), what Bjarne Stroustrup did he additional the thing orientated half, by treating code like life objects. What makes C++ therefore lovely is that it’s the speed of C and it’s additionally a high-level programing language, therefore allow us to say the most effective of each world. However on the opposite hand, C++ is challenging to be noted to newbies, and for an equivalent code that you wrote on C++, you’ll be able to write in Python for the quarter of the time.
Features of C++:
The five best features of C++ are:-
- It is the most primarily used language in competitive programming as far as facts go. Most of the extremely rated coders typically use C++ for cryptography. You’ll see it on any online websites.
- STL (standard guide library): It’s an extremely time-saver for people who recognize C and still writing code for bubble type.
- Operator overloading
- Multiple inheritances. Voluminous languages don’t have this facility.
- Ability to modularize code, encapsulation, and polymorphism after all.
Key takeaway
The C++ language is an object-oriented programming language & is a combination of both low-level & high-level language – a Middle-Level Language. The programming language was created, designed & developed by a Danish Computer Scientist – Bjarne Stroustrup at Bell Telephone Laboratories (now known as Nokia Bell Labs) in Murray Hill, New Jersey. As he wanted a flexible & a dynamic language which was similar to C with all its features, but with additionality of active type checking, basic inheritance, default functioning argument, classes, inlining, etc. and hence C with Classes (C++) was launched.
The prime purpose of C++ programming was to add object orientation to the C programming language, which is in itself one of the most powerful programming languages.
The core of the pure object-oriented programming is to create an object, in code, that has certain properties and methods. While designing C++ modules, we try to see whole world in the form of objects. For example a car is an object which has certain properties such as colour, number of doors, and the like. It also has certain methods such as accelerate, brake, and so on.
There are a few principle concepts that form the foundation of object-oriented programming −
This is the basic unit of object oriented programming. That is both data and function that operate on data are bundled as a unit called as object.
When you define a class, you define a blueprint for an object. This doesn't actually define any data, but it does define what the class name means, that is, what an object of the class will consist of and what operations can be performed on such an object.
Data abstraction refers to, providing only essential information to the outside world and hiding their background details, i.e., to represent the needed information in program without presenting the details.
For example, a database system hides certain details of how data is stored and created and maintained. Similar way, C++ classes provides different methods to the outside world without giving internal detail about those methods and data.
Encapsulation is placing the data and the functions that work on that data in the same place. While working with procedural languages, it is not always clear which functions work on which variables but object-oriented programming provides you framework to place the data and the relevant functions together in the same object.
One of the most useful aspects of object-oriented programming is code reusability. As the name suggests Inheritance is the process of forming a new class from an existing class that is from the existing class called as base class, new class is formed called as derived class.
This is a very important concept of object-oriented programming since this feature helps to reduce the code size.
The ability to use an operator or function in different ways in other words giving different meaning or functions to the operators or functions is called polymorphism. Poly refers to many. That is a single function or an operator functioning in many ways different upon the usage is called polymorphism.
The concept of overloading is also a branch of polymorphism. When the exiting operator or function is made to operate on new data type, it is said to be overloaded.
Key takeaway
The prime purpose of C++ programming was to add object orientation to the C programming language, which is in itself one of the most powerful programming languages.
The core of the pure object-oriented programming is to create an object, in code, that has certain properties and methods. While designing C++ modules, we try to see whole world in the form of objects. For example a car is an object which has certain properties such as color, number of doors, and the like. It also has certain methods such as accelerate, brake, and so on.
In C++, a structure is the same as a class except for a few differences. The most important of them is security. A Structure is not secure and cannot hide its implementation details from the end user while a class is secure and can hide its programming and designing details. Following are the points that expound on this difference:
1) Members of a class are private by default and members of a struct are public by default.
For example program 1 fails in compilation and program 2 works fine.
// Program 1 #include <stdio.h>
class Test { int x; // x is private }; int main() { Test t; t.x = 20; // compiler error because x is private getchar(); return 0; } |
// Program 2 #include <stdio.h>
struct Test { int x; // x is public }; int main() { Test t; t.x = 20; // works fine because x is public getchar(); return 0; } |
2) When deriving a struct from a class/struct, default access-specifier for a base class/struct is public. And when deriving a class, default access specifier is private.
For example program 3 fails in compilation and program 4 works fine.
// Program 3 #include <stdio.h>
class Base { public: int x; };
class Derived : Base { }; // is equilalent to class Derived : private Base {}
int main() { Derived d; d.x = 20; // compiler error becuase inheritance is private getchar(); return 0; } |
// Program 4 #include <stdio.h>
class Base { public: int x; };
struct Derived : Base { }; // is equilalent to struct Derived : public Base {}
int main() { Derived d; d.x = 20; // works fine becuase inheritance is public getchar(); return 0; } |
Key takeaway
In C++, a structure is the same as a class except for a few differences. The most important of them is security. A Structure is not secure and cannot hide its implementation details from the end user while a class is secure and can hide its programming and designing details. Following are the points that expound on this difference:
1) Members of a class are private by default and members of a struct are public by default.
The main purpose of C++ programming is to add object orientation to the C programming language and classes are the central feature of C++ that supports object-oriented programming and are often called user-defined types.
A class is used to specify the form of an object and it combines data representation and methods for manipulating that data into one neat package. The data and functions within a class are called members of the class.
When you define a class, you define a blueprint for a data type. This doesn't actually define any data, but it does define what the class name means, that is, what an object of the class will consist of and what operations can be performed on such an object.
A class definition starts with the keyword class followed by the class name; and the class body, enclosed by a pair of curly braces. A class definition must be followed either by a semicolon or a list of declarations. For example, we defined the Box data type using the keyword class as follows −
class Box {
public:
double length; // Length of a box
double breadth; // Breadth of a box
double height; // Height of a box
};
The keyword public determines the access attributes of the members of the class that follows it. A public member can be accessed from outside the class anywhere within the scope of the class object. You can also specify the members of a class as private or protected which we will discuss in a sub-section.
A class provides the blueprints for objects, so basically an object is created from a class. We declare objects of a class with exactly the same sort of declaration that we declare variables of basic types. Following statements declare two objects of class Box −
Box Box1; // Declare Box1 of type Box
Box Box2; // Declare Box2 of type Box
Both of the objects Box1 and Box2 will have their own copy of data members.
The public data members of objects of a class can be accessed using the direct member access operator (.). Let us try the following example to make the things clear −
#include <iostream>
using namespace std;
class Box {
public:
double length; // Length of a box
double breadth; // Breadth of a box
double height; // Height of a box
};
int main() {
Box Box1; // Declare Box1 of type Box
Box Box2; // Declare Box2 of type Box
double volume = 0.0; // Store the volume of a box here
// box 1 specification
Box1.height = 5.0;
Box1.length = 6.0;
Box1.breadth = 7.0;
// box 2 specification
Box2.height = 10.0;
Box2.length = 12.0;
Box2.breadth = 13.0;
// volume of box 1
volume = Box1.height * Box1.length * Box1.breadth;
cout << "Volume of Box1 : " << volume <<endl;
// volume of box 2
volume = Box2.height * Box2.length * Box2.breadth;
cout << "Volume of Box2 : " << volume <<endl;
return 0;
}
When the above code is compiled and executed, it produces the following result −
Volume of Box1 : 210
Volume of Box2 : 1560
It is important to note that private and protected members can not be accessed directly using direct member access operator (.). We will learn how private and protected members can be accessed.
So far, you have got very basic idea about C++ Classes and Objects. There are further interesting concepts related to C++ Classes and Objects which we will discuss in various sub-sections listed below −
Sr.No | Concept & Description |
1 | Class Member Functions A member function of a class is a function that has its definition or its prototype within the class definition like any other variable. |
2 | Class Access Modifiers A class member can be defined as public, private or protected. By default members would be assumed as private. |
3 | Constructor and Destructor A class constructor is a special function in a class that is called when a new object of the class is created. A destructor is also a special function which is called when created object is deleted. |
4 | Copy Constructor The copy constructor is a constructor which creates an object by initializing it with an object of the same class, which has been created previously. |
5 | Friend Functions A friend function is permitted full access to private and protected members of a class. |
6 | Inline Functions With an inline function, the compiler tries to expand the code in the body of the function in place of a call to the function. |
7 | This pointer Every object has a special pointer this which points to the object itself. |
8 | Pointers to C++ Class A pointer to a class is done exactly the same way a pointer to a structure is. In fact a class is really just a structure with functions in it. |
9 | Static Members of a Class Both data members and function members of a class can be declared as static. |
Key takeaway
The main purpose of C++ programming is to add object orientation to the C programming language and classes are the central feature of C++ that supports object-oriented programming and are often called user-defined types.
A class is used to specify the form of an object and it combines data representation and methods for manipulating that data into one neat package. The data and functions within a class are called members of the class.
All C++ programs are composed of the following two fundamental elements −
- Program statements (code) − This is the part of a program that performs actions and they are called functions.
- Program data − The data is the information of the program which gets affected by the program functions.
Encapsulation is an Object Oriented Programming concept that binds together the data and functions that manipulate the data, and that keeps both safe from outside interference and misuse. Data encapsulation led to the important OOP concept of data hiding.
Data encapsulation is a mechanism of bundling the data, and the functions that use them and data abstraction is a mechanism of exposing only the interfaces and hiding the implementation details from the user.
C++ supports the properties of encapsulation and data hiding through the creation of user-defined types, called classes. We already have studied that a class can contain private, protected and public members. By default, all items defined in a class are private. For example −
class Box {
public:
double getVolume(void) {
return length * breadth * height;
}
private:
double length; // Length of a box
double breadth; // Breadth of a box
double height; // Height of a box
};
The variables length, breadth, and height are private. This means that they can be accessed only by other members of the Box class, and not by any other part of your program. This is one way encapsulation is achieved.
To make parts of a class public (i.e., accessible to other parts of your program), you must declare them after the public keyword. All variables or functions defined after the public specifier are accessible by all other functions in your program.
Making one class a friend of another exposes the implementation details and reduces encapsulation. The ideal is to keep as many of the details of each class hidden from all other classes as possible.
Any C++ program where you implement a class with public and private members is an example of data encapsulation and data abstraction. Consider the following example −
#include <iostream>
using namespace std;
class Adder {
public:
// constructor
Adder(int i = 0) {
total = i;
}
// interface to outside world
void addNum(int number) {
total += number;
}
// interface to outside world
int getTotal() {
return total;
};
private:
// hidden data from outside world
int total;
};
int main() {
Adder a;
a.addNum(10);
a.addNum(20);
a.addNum(30);
cout << "Total " << a.getTotal() <<endl;
return 0;
}
When the above code is compiled and executed, it produces the following result −
Total 60
Above class adds numbers together, and returns the sum. The public members addNum and getTotal are the interfaces to the outside world and a user needs to know them to use the class. The private member total is something that is hidden from the outside world, but is needed for the class to operate properly.
Most of us have learnt to make class members private by default unless we really need to expose them. That's just good encapsulation.
This is applied most frequently to data members, but it applies equally to all members, including virtual functions.
Key takeaway
Encapsulation is an Object Oriented Programming concept that binds together the data and functions that manipulate the data, and that keeps both safe from outside interference and misuse. Data encapsulation led to the important OOP concept of data hiding.
Data encapsulation is a mechanism of bundling the data, and the functions that use them and data abstraction is a mechanism of exposing only the interfaces and hiding the implementation details from the user.
- Data Abstraction is a process of providing only the essential details to the outside world and hiding the internal details, i.e., representing only the essential details in the program.
- Data Abstraction is a programming technique that depends on the seperation of the interface and implementation details of the program.
- Let's take a real life example of AC, which can be turned ON or OFF, change the temperature, change the mode, and other external components such as fan, swing. But, we don't know the internal details of the AC, i.e., how it works internally. Thus, we can say that AC seperates the implementation details from the external interface.
- C++ provides a great level of abstraction. For example, pow() function is used to calculate the power of a number without knowing the algorithm the function follows.
In C++ program if we implement class with private and public members then it is an example of data abstraction.
Data Abstraction can be achieved in two ways:
- Abstraction using classes
- Abstraction in header files.
Fig 1 – Data Abstraction
Abstraction using classes: An abstraction can be achieved using classes. A class is used to group all the data members and member functions into a single unit by using the access specifiers. A class has the responsibility to determine which data member is to be visible outside and which is not.
Abstraction in header files: An another type of abstraction is header file. For example, pow() function available is used to calculate the power of a number without actually knowing which algorithm function uses to calculate the power. Thus, we can say that header files hides all the implementation details from the user.
Access Specifiers Implement Abstraction:
- Public specifier: When the members are declared as public, members can be accessed anywhere from the program.
- Private specifier: When the members are declared as private, members can only be accessed only by the member functions of the class.
Let's see a simple example of abstraction in header files.
// program to calculate the power of a number.
- #include <iostream>
- #include<math.h>
- using namespace std;
- int main()
- {
- int n = 4;
- int power = 3;
- int result = pow(n,power); // pow(n,power) is the power function
- std::cout << "Cube of n is : " <<result<< std::endl;
- return 0;
- }
Output:
Cube of n is : 64
In the above example, pow() function is used to calculate 4 raised to the power 3. The pow() function is present in the math.h header file in which all the implementation details of the pow() function is hidden.
Let's see a simple example of data abstraction using classes.
- #include <iostream>
- using namespace std;
- class Sum
- {
- private: int x, y, z; // private variables
- public:
- void add()
- {
- cout<<"Enter two numbers: ";
- cin>>x>>y;
- z= x+y;
- cout<<"Sum of two number is: "<<z<<endl;
- }
- };
- int main()
- {
- Sum sm;
- sm.add();
- return 0;
- }
Output:
Enter two numbers:
3
6
Sum of two number is: 9
In the above example, abstraction is achieved using classes. A class 'Sum' contains the private members x, y and z are only accessible by the member functions of the class.
- Implementation details of the class are protected from the inadvertent user level errors.
- A programmer does not need to write the low level code.
- Data Abstraction avoids the code duplication, i.e., programmer does not have to undergo the same tasks every time to perform the similar operation.
- The main aim of the data abstraction is to reuse the code and the proper partitioning of the code across the classes.
- Internal implementation can be changed without affecting the user level code.
Key takeaway
- Data Abstraction is a process of providing only the essential details to the outside world and hiding the internal details, i.e., representing only the essential details in the program.
- Data Abstraction is a programming technique that depends on the seperation of the interface and implementation details of the program.
- Let's take a real life example of AC, which can be turned ON or OFF, change the temperature, change the mode, and other external components such as fan, swing. But, we don't know the internal details of the AC, i.e., how it works internally. Thus, we can say that AC seperates the implementation details from the external interface.
In C++, inheritance is a process in which one object acquires all the properties and behaviours of its parent object automatically. In such way, you can reuse, extend or modify the attributes and behaviours which are defined in other class.
In C++, the class which inherits the members of another class is called derived class and the class whose members are inherited is called base class. The derived class is the specialized class for the base class.
Code reusability: Now you can reuse the members of your parent class. So, there is no need to define the member again. So less code is required in the class.
C++ supports five types of inheritance:
- Single inheritance
- Multiple inheritance
- Hierarchical inheritance
- Multilevel inheritance
- Hybrid inheritance
Fig 2 - Inheritance
A Derived class is defined as the class derived from the base class.
The Syntax of Derived class:
- class derived_class_name :: visibility-mode base_class_name
- {
- // body of the derived class.
- }
Where,
derived_class_name: It is the name of the derived class.
visibility mode: The visibility mode specifies whether the features of the base class are publicly inherited or privately inherited. It can be public or private.
base_class_name: It is the name of the base class.
- When the base class is privately inherited by the derived class, public members of the base class becomes the private members of the derived class. Therefore, the public members of the base class are not accessible by the objects of the derived class only by the member functions of the derived class.
- When the base class is publicly inherited by the derived class, public members of the base class also become the public members of the derived class. Therefore, the public members of the base class are accessible by the objects of the derived class as well as by the member functions of the base class.
- In C++, the default mode of visibility is private.
- The private members of the base class are never inherited.
Single inheritance is defined as the inheritance in which a derived class is inherited from the only one base class.
Fig 3 – Single Inheritance
Where 'A' is the base class, and 'B' is the derived class.
C++ Single Level Inheritance Example: Inheriting Fields
When one class inherits another class, it is known as single level inheritance. Let's see the example of single level inheritance which inherits the fields only.
- #include <iostream>
- using namespace std;
- class Account {
- public:
- float salary = 60000;
- };
- class Programmer: public Account {
- public:
- float bonus = 5000;
- };
- int main(void) {
- Programmer p1;
- cout<<"Salary: "<<p1.salary<<endl;
- cout<<"Bonus: "<<p1.bonus<<endl;
- return 0;
- }
Output:
Salary: 60000
Bonus: 5000
In the above example, Employee is the base class and Programmer is the derived class.
C++ Single Level Inheritance Example: Inheriting Methods
Let's see another example of inheritance in C++ which inherits methods only.
- #include <iostream>
- using namespace std;
- class Animal {
- public:
- void eat() {
- cout<<"Eating..."<<endl;
- }
- };
- class Dog: public Animal
- {
- public:
- void bark(){
- cout<<"Barking...";
- }
- };
- int main(void) {
- Dog d1;
- d1.eat();
- d1.bark();
- return 0;
- }
Output:
Eating...
Barking...
Let's see a simple example.
- #include <iostream>
- using namespace std;
- class A
- {
- int a = 4;
- int b = 5;
- public:
- int mul()
- {
- int c = a*b;
- return c;
- }
- };
- class B : private A
- {
- public:
- void display()
- {
- int result = mul();
- std::cout <<"Multiplication of a and b is : "<<result<< std::endl;
- }
- };
- int main()
- {
- B b;
- b.display();
- return 0;
- }
Output:
Multiplication of a and b is : 20
In the above example, class A is privately inherited. Therefore, the mul() function of class 'A' cannot be accessed by the object of class B. It can only be accessed by the member function of class B.
How to make a Private Member Inheritable
The private member is not inheritable. If we modify the visibility mode by making it public, but this takes away the advantage of data hiding.
C++ introduces a third visibility modifier, i.e., protected. The member which is declared as protected will be accessible to all the member functions within the class as well as the class immediately derived from it.
Visibility modes can be classified into three categories:
Fig 4 – Visibility modes
- Public: When the member is declared as public, it is accessible to all the functions of the program.
- Private: When the member is declared as private, it is accessible within the class only.
- Protected: When the member is declared as protected, it is accessible within its own class as well as the class immediately derived from it.
Visibility of Inherited Members
Base class visibility | Derived class visibility | ||
Public | Private | Protected | |
Private | Not Inherited | Not Inherited | Not Inherited |
Protected | Protected | Private | Protected |
Public | Public | Private | Protected |
Multilevel inheritance is a process of deriving a class from another derived class.
Fig 5 - Multi Level Inheritance
C++ Multi Level Inheritance Example
When one class inherits another class which is further inherited by another class, it is known as multi level inheritance in C++. Inheritance is transitive so the last derived class acquires all the members of all its base classes.
Let's see the example of multi level inheritance in C++.
- #include <iostream>
- using namespace std;
- class Animal {
- public:
- void eat() {
- cout<<"Eating..."<<endl;
- }
- };
- class Dog: public Animal
- {
- public:
- void bark(){
- cout<<"Barking..."<<endl;
- }
- };
- class BabyDog: public Dog
- {
- public:
- void weep() {
- cout<<"Weeping...";
- }
- };
- int main(void) {
- BabyDog d1;
- d1.eat();
- d1.bark();
- d1.weep();
- return 0;
- }
Output:
Eating...
Barking...
Weeping...
Multiple inheritance is the process of deriving a new class that inherits the attributes from two or more classes.
Fig 6 – Derived Class
Syntax of the Derived class:
- class D : visibility B-1, visibility B-2, ?
- {
- // Body of the class;
- }
Let's see a simple example of multiple inheritance.
- #include <iostream>
- using namespace std;
- class A
- {
- protected:
- int a;
- public:
- void get_a(int n)
- {
- a = n;
- }
- };
- class B
- {
- protected:
- int b;
- public:
- void get_b(int n)
- {
- b = n;
- }
- };
- class C : public A,public B
- {
- public:
- void display()
- {
- std::cout << "The value of a is : " <<a<< std::endl;
- std::cout << "The value of b is : " <<b<< std::endl;
- cout<<"Addition of a and b is : "<<a+b;
- }
- };
- int main()
- {
- C c;
- c.get_a(10);
- c.get_b(20);
- c.display();
- return 0;
- }
Output:
The value of a is : 10
The value of b is : 20
Addition of a and b is : 30
In the above example, class 'C' inherits two base classes 'A' and 'B' in a public mode.
Ambiguity Resolution in Inheritance
Ambiguity can be occurred in using the multiple inheritance when a function with the same name occurs in more than one base class.
Let's understand this through an example:
- #include <iostream>
- using namespace std;
- class A
- {
- public:
- void display()
- {
- std::cout << "Class A" << std::endl;
- }
- };
- class B
- {
- public:
- void display()
- {
- std::cout << "Class B" << std::endl;
- }
- };
- class C : public A, public B
- {
- void view()
- {
- display();
- }
- };
- int main()
- {
- C c;
- c.display();
- return 0;
- }
Output:
error: reference to 'display' is ambiguous
display();
- The above issue can be resolved by using the class resolution operator with the function. In the above example, the derived class code can be rewritten as:
- class C : public A, public B
- {
- void view()
- {
- A :: display(); // Calling the display() function of class A.
- B :: display(); // Calling the display() function of class B.
- }
- };
An ambiguity can also occur in single inheritance.
Consider the following situation:
- class A
- {
- public:
- void display()
- {
- cout<<?Class A?;
- }
- } ;
- class B
- {
- public:
- void display()
- {
- cout<<?Class B?;
- }
- } ;
In the above case, the function of the derived class overrides the method of the base class. Therefore, call to the display() function will simply call the function defined in the derived class. If we want to invoke the base class function, we can use the class resolution operator.
- int main()
- {
- B b;
- b.display(); // Calling the display() function of B class.
- b.B :: display(); // Calling the display() function defined in B class.
- }
Hybrid inheritance is a combination of more than one type of inheritance.
Fig 7 – Hybrid Inheritance
Let's see a simple example:
- #include <iostream>
- using namespace std;
- class A
- {
- protected:
- int a;
- public:
- void get_a()
- {
- std::cout << "Enter the value of 'a' : " << std::endl;
- cin>>a;
- }
- };
- class B : public A
- {
- protected:
- int b;
- public:
- void get_b()
- {
- std::cout << "Enter the value of 'b' : " << std::endl;
- cin>>b;
- }
- };
- class C
- {
- protected:
- int c;
- public:
- void get_c()
- {
- std::cout << "Enter the value of c is : " << std::endl;
- cin>>c;
- }
- };
- class D : public B, public C
- {
- protected:
- int d;
- public:
- void mul()
- {
- get_a();
- get_b();
- get_c();
- std::cout << "Multiplication of a,b,c is : " <<a*b*c<< std::endl;
- }
- };
- int main()
- {
- D d;
- d.mul();
- return 0;
- }
Output:
Enter the value of 'a' :
10
Enter the value of 'b' :
20
Enter the value of c is :
30
Multiplication of a,b,c is : 6000
Hierarchical inheritance is defined as the process of deriving more than one class from a base class.
Fig 8 – Hierarchical Inheritance
Syntax of Hierarchical inheritance:
- class A
- {
- // body of the class A.
- }
- class B : public A
- {
- // body of class B.
- }
- class C : public A
- {
- // body of class C.
- }
- class D : public A
- {
- // body of class D.
- }
Let's see a simple example:
- #include <iostream>
- using namespace std;
- class Shape // Declaration of base class.
- {
- public:
- int a;
- int b;
- void get_data(int n,int m)
- {
- a= n;
- b = m;
- }
- };
- class Rectangle : public Shape // inheriting Shape class
- {
- public:
- int rect_area()
- {
- int result = a*b;
- return result;
- }
- };
- class Triangle : public Shape // inheriting Shape class
- {
- public:
- int triangle_area()
- {
- float result = 0.5*a*b;
- return result;
- }
- };
- int main()
- {
- Rectangle r;
- Triangle t;
- int length,breadth,base,height;
- std::cout << "Enter the length and breadth of a rectangle: " << std::endl;
- cin>>length>>breadth;
- r.get_data(length,breadth);
- int m = r.rect_area();
- std::cout << "Area of the rectangle is : " <<m<< std::endl;
- std::cout << "Enter the base and height of the triangle: " << std::endl;
- cin>>base>>height;
- t.get_data(base,height);
- float n = t.triangle_area();
- std::cout <<"Area of the triangle is : " << n<<std::endl;
- return 0;
- }
Output:
Enter the length and breadth of a rectangle:
23
20
Area of the rectangle is : 460
Enter the base and height of the triangle:
2
5
Area of the triangle is : 5
Key takeaway
In C++, inheritance is a process in which one object acquires all the properties and behaviours of its parent object automatically. In such way, you can reuse, extend or modify the attributes and behaviours which are defined in other class.
In C++, the class which inherits the members of another class is called derived class and the class whose members are inherited is called base class. The derived class is the specialized class for the base class.
Code reusability: Now you can reuse the members of your parent class. So, there is no need to define the member again. So less code is required in the class.
C++ inline function is powerful concept that is commonly used with classes. If a function is inline, the compiler places a copy of the code of that function at each point where the function is called at compile time.
Any change to an inline function could require all clients of the function to be recompiled because compiler would need to replace all the code once again otherwise it will continue with old functionality.
To inline a function, place the keyword inline before the function name and define the function before any calls are made to the function. The compiler can ignore the inline qualifier in case defined function is more than a line.
A function definition in a class definition is an inline function definition, even without the use of the inline specifier.
Following is an example, which makes use of inline function to return max of two numbers −
#include <iostream>
using namespace std;
inline int Max(int x, int y) {
return (x > y)? x : y;
}
// Main function for the program
int main() {
cout << "Max (20,10): " << Max(20,10) << endl;
cout << "Max (0,200): " << Max(0,200) << endl;
cout << "Max (100,1010): " << Max(100,1010) << endl;
return 0;
}
When the above code is compiled and executed, it produces the following result −
Max (20,10): 20
Max (0,200): 200
Max (100,1010): 1010
Key takeaway
C++ inline function is powerful concept that is commonly used with classes. If a function is inline, the compiler places a copy of the code of that function at each point where the function is called at compile time.
Any change to an inline function could require all clients of the function to be recompiled because compiler would need to replace all the code once again otherwise it will continue with old functionality.
To inline a function, place the keyword inline before the function name and define the function before any calls are made to the function. The compiler can ignore the inline qualifier in case defined function is more than a line.
In C++, constructor is a special method which is invoked automatically at the time of object creation. It is used to initialize the data members of new object generally. The constructor in C++ has the same name as class or structure.
There can be two types of constructors in C++.
- Default constructor
- Parameterized constructor
A constructor which has no argument is known as default constructor. It is invoked at the time of creating object.
Let's see the simple example of C++ default Constructor.
- #include <iostream>
- using namespace std;
- class Employee
- {
- public:
- Employee()
- {
- cout<<"Default Constructor Invoked"<<endl;
- }
- };
- int main(void)
- {
- Employee e1; //creating an object of Employee
- Employee e2;
- return 0;
- }
Output:
Default Constructor Invoked
Default Constructor Invoked
A constructor which has parameters is called parameterized constructor. It is used to provide different values to distinct objects.
Let's see the simple example of C++ Parameterized Constructor.
#include <iostream>
using namespace std;
class Employee {
public:
int id;//data member (also instance variable)
string name;//data member(also instance variable)
float salary;
Employee(int i, string n, float s)
{
id = i;
name = n;
salary = s;
}
void display()
{
cout<<id<<" "<<name<<" "<<salary<<endl;
}
};
int main(void) {
Employee e1 =Employee(101, "Sonoo", 890000); //creating an object of Employee
Employee e2=Employee(102, "Nakul", 59000);
e1.display();
e2.display();
return 0;
}
Output:
101 Sonoo 890000
102 Nakul 59000
A destructor works opposite to constructor; it destructs the objects of classes. It can be defined only once in a class. Like constructors, it is invoked automatically.
A destructor is defined like constructor. It must have same name as class. But it is prefixed with a tilde sign (~).
Note: C++ destructor cannot have parameters. Moreover, modifiers can't be applied on destructors.
C++ Constructor and Destructor Example
Let's see an example of constructor and destructor in C++ which is called automatically.
- #include <iostream>
- using namespace std;
- class Employee
- {
- public:
- Employee()
- {
- cout<<"Constructor Invoked"<<endl;
- }
- ~Employee()
- {
- cout<<"Destructor Invoked"<<endl;
- }
- };
- int main(void)
- {
- Employee e1; //creating an object of Employee
- Employee e2; //creating an object of Employee
- return 0;
- }
Output:
Constructor Invoked
Constructor Invoked
Destructor Invoked
Destructor Invoked
Key takeaway
In C++, constructor is a special method which is invoked automatically at the time of object creation. It is used to initialize the data members of new object generally. The constructor in C++ has the same name as class or structure.
There can be two types of constructors in C++.
- Default constructor
- Parameterized constructor
If we create two or more members having the same name but different in number or type of parameter, it is known as C++ overloading. In C++, we can overload:
- methods,
- constructors, and
- indexed properties
It is because these members have parameters only.
Types of overloading in C++ are:
- Function overloading
- Operator overloading
Fig 9 - Overloading
Function Overloading is defined as the process of having two or more function with the same name, but different in parameters is known as function overloading in C++. In function overloading, the function is redefined by using either different types of arguments or a different number of arguments. It is only through these differences compiler can differentiate between the functions.
The advantage of Function overloading is that it increases the readability of the program because you don't need to use different names for the same action.
C++ Function Overloading Example
Let's see the simple example of function overloading where we are changing number of arguments of add() method.
// program of function overloading when number of arguments vary.
- #include <iostream>
- using namespace std;
- class Cal {
- public:
- static int add(int a,int b){
- return a + b;
- }
- static int add(int a, int b, int c)
- {
- return a + b + c;
- }
- };
- int main(void) {
- Cal C; // class object declaration.
- cout<<C.add(10, 20)<<endl;
- cout<<C.add(12, 20, 23);
- return 0;
- }
Output:
30
55
Let's see the simple example when the type of the arguments vary.
// Program of function overloading with different types of arguments.
- #include<iostream>
- using namespace std;
- int mul(int,int);
- float mul(float,int);
- int mul(int a,int b)
- {
- return a*b;
- }
- float mul(double x, int y)
- {
- return x*y;
- }
- int main()
- {
- int r1 = mul(6,7);
- float r2 = mul(0.2,3);
- std::cout << "r1 is : " <<r1<< std::endl;
- std::cout <<"r2 is : " <<r2<< std::endl;
- return 0;
- }
Output:
r1 is : 42
r2 is : 0.6
Function Overloading and Ambiguity
When the compiler is unable to decide which function is to be invoked among the overloaded function, this situation is known as function overloading.
When the compiler shows the ambiguity error, the compiler does not run the program.
Causes of Function Overloading:
- Type Conversion.
- Function with default arguments.
- Function with pass by reference.
Fig 10 – Causes of ambiquity
- Type Conversion:
Let's see a simple example.
- #include<iostream>
- using namespace std;
- void fun(int);
- void fun(float);
- void fun(int i)
- {
- std::cout << "Value of i is : " <<i<< std::endl;
- }
- void fun(float j)
- {
- std::cout << "Value of j is : " <<j<< std::endl;
- }
- int main()
- {
- fun(12);
- fun(1.2);
- return 0;
- }
The above example shows an error "call of overloaded 'fun(double)' is ambiguous". The fun(10) will call the first function. The fun(1.2) calls the second function according to our prediction. But, this does not refer to any function as in C++, all the floating point constants are treated as double not as a float. If we replace float to double, the program works. Therefore, this is a type conversion from float to double.
- Function with Default Arguments
Let's see a simple example.
- #include<iostream>
- using namespace std;
- void fun(int);
- void fun(int,int);
- void fun(int i)
- {
- std::cout << "Value of i is : " <<i<< std::endl;
- }
- void fun(int a,int b=9)
- {
- std::cout << "Value of a is : " <<a<< std::endl;
- std::cout << "Value of b is : " <<b<< std::endl;
- }
- int main()
- {
- fun(12);
- return 0;
- }
The above example shows an error "call of overloaded 'fun(int)' is ambiguous". The fun(int a, int b=9) can be called in two ways: first is by calling the function with one argument, i.e., fun(12) and another way is calling the function with two arguments, i.e., fun(4,5). The fun(int i) function is invoked with one argument. Therefore, the compiler could not be able to select among fun(int i) and fun(int a,int b=9).
- Function with pass by reference
Let's see a simple example.
- #include <iostream>
- using namespace std;
- void fun(int);
- void fun(int &);
- int main()
- {
- int a=10;
- fun(a); // error, which f()?
- return 0;
- }
- void fun(int x)
- {
- std::cout << "Value of x is : " <<x<< std::endl;
- }
- void fun(int &b)
- {
- std::cout << "Value of b is : " <<b<< std::endl;
- }
The above example shows an error "call of overloaded 'fun(int&)' is ambiguous". The first function takes one integer argument and the second function takes a reference parameter as an argument. In this case, the compiler does not know which function is needed by the user as there is no syntactical difference between the fun(int) and fun(int &).
Operator overloading is a compile-time polymorphism in which the operator is overloaded to provide the special meaning to the user-defined data type. Operator overloading is used to overload or redefines most of the operators available in C++. It is used to perform the operation on the user-defined data type. For example, C++ provides the ability to add the variables of the user-defined data type that is applied to the built-in data types.
The advantage of Operators overloading is to perform different operations on the same operand.
Operator that cannot be overloaded are as follows:
- Scope operator (::)
- Sizeof
- member selector(.)
- member pointer selector(*)
- ternary operator(?:)
Syntax of Operator Overloading
- return_type class_name : : operator op(argument_list)
- {
- // body of the function.
- }
Where the return type is the type of value returned by the function.
class_name is the name of the class.
operator op is an operator function where op is the operator being overloaded, and the operator is the keyword.
Rules for Operator Overloading
- Existing operators can only be overloaded, but the new operators cannot be overloaded.
- The overloaded operator contains atleast one operand of the user-defined data type.
- We cannot use friend function to overload certain operators. However, the member function can be used to overload those operators.
- When unary operators are overloaded through a member function take no explicit arguments, but, if they are overloaded by a friend function, takes one argument.
- When binary operators are overloaded through a member function takes one explicit argument, and if they are overloaded through a friend function takes two explicit arguments.
C++ Operators Overloading Example
Let's see the simple example of operator overloading in C++. In this example, void operator ++ () operator function is defined (inside Test class).
// program to overload the unary operator ++.
- #include <iostream>
- using namespace std;
- class Test
- {
- private:
- int num;
- public:
- Test(): num(8){}
- void operator ++() {
- num = num+2;
- }
- void Print() {
- cout<<"The Count is: "<<num;
- }
- };
- int main()
- {
- Test tt;
- ++tt; // calling of a function "void operator ++()"
- tt.Print();
- return 0;
- }
Output:
The Count is: 10
Let's see a simple example of overloading the binary operators.
// program to overload the binary operators.
- #include <iostream>
- using namespace std;
- class A
- {
- int x;
- public:
- A(){}
- A(int i)
- {
- x=i;
- }
- void operator+(A);
- void display();
- };
- void A :: operator+(A a)
- {
- int m = x+a.x;
- cout<<"The result of the addition of two objects is : "<<m;
- }
- int main()
- {
- A a1(5);
- A a2(4);
- a1+a2;
- return 0;
- }
Output:
The result of the addition of two objects is : 9
Key takeaway
If we create two or more members having the same name but different in number or type of parameter, it is known as C++ overloading. In C++, we can overload:
- methods,
- constructors, and
- indexed properties
It is because these members have parameters only.
We can define class members static using static keyword. When we declare a member of a class as static it means no matter how many objects of the class are created, there is only one copy of the static member.
A static member is shared by all objects of the class. All static data is initialized to zero when the first object is created, if no other initialization is present. We can't put it in the class definition but it can be initialized outside the class as done in the following example by redeclaring the static variable, using the scope resolution operator :: to identify which class it belongs to.
Let us try the following example to understand the concept of static data members −
#include <iostream>
using namespace std;
class Box {
public:
static int objectCount;
// Constructor definition
Box(double l = 2.0, double b = 2.0, double h = 2.0) {
cout <<"Constructor called." << endl;
length = l;
breadth = b;
height = h;
// Increase every time object is created
objectCount++;
}
double Volume() {
return length * breadth * height;
}
private:
double length; // Length of a box
double breadth; // Breadth of a box
double height; // Height of a box
};
// Initialize static member of class Box
int Box::objectCount = 0;
int main(void) {
Box Box1(3.3, 1.2, 1.5); // Declare box1
Box Box2(8.5, 6.0, 2.0); // Declare box2
// Print total number of objects.
cout << "Total objects: " << Box::objectCount << endl;
return 0;
}
When the above code is compiled and executed, it produces the following result −
Constructor called.
Constructor called.
Total objects: 2
By declaring a function member as static, you make it independent of any particular object of the class. A static member function can be called even if no objects of the class exist and the static functions are accessed using only the class name and the scope resolution operator ::.
A static member function can only access static data member, other static member functions and any other functions from outside the class.
Static member functions have a class scope and they do not have access to the this pointer of the class. You could use a static member function to determine whether some objects of the class have been created or not.
Let us try the following example to understand the concept of static function members −
#include <iostream>
using namespace std;
class Box {
public:
static int objectCount;
// Constructor definition
Box(double l = 2.0, double b = 2.0, double h = 2.0) {
cout <<"Constructor called." << endl;
length = l;
breadth = b;
height = h;
// Increase every time object is created
objectCount++;
}
double Volume() {
return length * breadth * height;
}
static int getCount() {
return objectCount;
}
private:
double length; // Length of a box
double breadth; // Breadth of a box
double height; // Height of a box
};
// Initialize static member of class Box
int Box::objectCount = 0;
int main(void) {
// Print total number of objects before creating object.
cout << "Inital Stage Count: " << Box::getCount() << endl;
Box Box1(3.3, 1.2, 1.5); // Declare box1
Box Box2(8.5, 6.0, 2.0); // Declare box2
// Print total number of objects after creating object.
cout << "Final Stage Count: " << Box::getCount() << endl;
return 0;
}
When the above code is compiled and executed, it produces the following result −
Inital Stage Count: 0
Constructor called.
Constructor called.
Final Stage Count: 2
Key takeaway
We can define class members static using static keyword. When we declare a member of a class as static it means no matter how many objects of the class are created, there is only one copy of the static member.
A static member is shared by all objects of the class. All static data is initialized to zero when the first object is created, if no other initialization is present. We can't put it in the class definition but it can be initialized outside the class as done in the following example by redeclaring the static variable, using the scope resolution operator :: to identify which class it belongs to.
The :: (scope resolution) operator is used to get hidden names due to variable scopes so that you can still use them. The scope resolution operator can be used as both unary and binary. You can use the unary scope operator if a namespace scope or global scope name is hidden by a particular declaration of an equivalent name during a block or class. For example, if you have a global variable of name my_var and a local variable of name my_var, to access global my_var, you'll need to use the scope resolution operator.
#include <iostream>
using namespace std;
int my_var = 0;
int main(void) {
int my_var = 0;
::my_var = 1; // set global my_var to 1
my_var = 2; // set local my_var to 2
cout << ::my_var << ", " << my_var;
return 0;
}
This will give the output −
1, 2
The declaration of my_var declared in the main function hides the integer named my_var declared in global namespace scope. The statement ::my_var = 1 accesses the variable named my_var declared in global namespace scope.
You can also use the scope resolution operator to use class names or class member names. If a class member name is hidden, you can use it by prefixing it with its class name and the class scope operator. For example,
#include <iostream>
using namespace std;
class X {
public:
static int count;
};
int X::count = 10; // define static data member
int main () {
int X = 0; // hides class type X
cout << X::count << endl; // use static member of class X
}
This will give the output −
10
Key takeaway
The :: (scope resolution) operator is used to get hidden names due to variable scopes so that you can still use them. The scope resolution operator can be used as both unary and binary. You can use the unary scope operator if a namespace scope or global scope name is hidden by a particular declaration of an equivalent name during a block or class. For example, if you have a global variable of name my_var and a local variable of name my_var, to access global my_var, you'll need to use the scope resolution operator.
A member function of a class is a function that has its definition or its prototype within the class definition like any other variable. It operates on any object of the class of which it is a member, and has access to all the members of a class for that object.
Let us take previously defined class to access the members of the class using a member function instead of directly accessing them −
class Box {
public:
double length; // Length of a box
double breadth; // Breadth of a box
double height; // Height of a box
double getVolume(void);// Returns box volume
};
Member functions can be defined within the class definition or separately using scope resolution operator, : −. Defining a member function within the class definition declares the function inline, even if you do not use the inline specifier. So either you can define Volume() function as below −
class Box {
public:
double length; // Length of a box
double breadth; // Breadth of a box
double height; // Height of a box
double getVolume(void) {
return length * breadth * height;
}
};
If you like, you can define the same function outside the class using the scope resolution operator (::) as follows −
double Box::getVolume(void) {
return length * breadth * height;
}
Here, only important point is that you would have to use class name just before :: operator. A member function will be called using a dot operator (.) on a object where it will manipulate data related to that object only as follows −
Box myBox; // Create an object
myBox.getVolume(); // Call member function for the object
Let us put above concepts to set and get the value of different class members in a class −
#include <iostream>
using namespace std;
class Box {
public:
double length; // Length of a box
double breadth; // Breadth of a box
double height; // Height of a box
// Member functions declaration
double getVolume(void);
void setLength( double len );
void setBreadth( double bre );
void setHeight( double hei );
};
// Member functions definitions
double Box::getVolume(void) {
return length * breadth * height;
}
void Box::setLength( double len ) {
length = len;
}
void Box::setBreadth( double bre ) {
breadth = bre;
}
void Box::setHeight( double hei ) {
height = hei;
}
// Main function for the program
int main() {
Box Box1; // Declare Box1 of type Box
Box Box2; // Declare Box2 of type Box
double volume = 0.0; // Store the volume of a box here
// box 1 specification
Box1.setLength(6.0);
Box1.setBreadth(7.0);
Box1.setHeight(5.0);
// box 2 specification
Box2.setLength(12.0);
Box2.setBreadth(13.0);
Box2.setHeight(10.0);
// volume of box 1
volume = Box1.getVolume();
cout << "Volume of Box1 : " << volume <<endl;
// volume of box 2
volume = Box2.getVolume();
cout << "Volume of Box2 : " << volume <<endl;
return 0;
}
When the above code is compiled and executed, it produces the following result −
Volume of Box1 : 210
Volume of Box2 : 1560
Data hiding is one of the important features of Object Oriented Programming which allows preventing the functions of a program to access directly the internal representation of a class type. The access restriction to the class members is specified by the labeled public, private, and protected sections within the class body. The keywords public, private, and protected are called access specifiers.
A class can have multiple public, protected, or private labeled sections. Each section remains in effect until either another section label or the closing right brace of the class body is seen. The default access for members and classes is private.
class Base {
public:
// public members go here
protected:
// protected members go here
private:
// private members go here
};
A public member is accessible from anywhere outside the class but within a program. You can set and get the value of public variables without any member function as shown in the following example −
#include <iostream>
using namespace std;
class Line {
public:
double length;
void setLength( double len );
double getLength( void );
};
// Member functions definitions
double Line::getLength(void) {
return length ;
}
void Line::setLength( double len) {
length = len;
}
// Main function for the program
int main() {
Line line;
// set line length
line.setLength(6.0);
cout << "Length of line : " << line.getLength() <<endl;
// set line length without member function
line.length = 10.0; // OK: because length is public
cout << "Length of line : " << line.length <<endl;
return 0;
}
When the above code is compiled and executed, it produces the following result −
Length of line : 6
Length of line : 10
A private member variable or function cannot be accessed, or even viewed from outside the class. Only the class and friend functions can access private members.
By default all the members of a class would be private, for example in the following class width is a private member, which means until you label a member, it will be assumed a private member −
class Box {
double width;
public:
double length;
void setWidth( double wid );
double getWidth( void );
};
Practically, we define data in private section and related functions in public section so that they can be called from outside of the class as shown in the following program.
#include <iostream>
using namespace std;
class Box {
public:
double length;
void setWidth( double wid );
double getWidth( void );
private:
double width;
};
// Member functions definitions
double Box::getWidth(void) {
return width ;
}
void Box::setWidth( double wid ) {
width = wid;
}
// Main function for the program
int main() {
Box box;
// set box length without member function
box.length = 10.0; // OK: because length is public
cout << "Length of box : " << box.length <<endl;
// set box width without member function
// box.width = 10.0; // Error: because width is private
box.setWidth(10.0); // Use member function to set it.
cout << "Width of box : " << box.getWidth() <<endl;
return 0;
}
When the above code is compiled and executed, it produces the following result −
Length of box : 10
Width of box : 10
A protected member variable or function is very similar to a private member but it provided one additional benefit that they can be accessed in child classes which are called derived classes.
You will learn derived classes and inheritance in next chapter. For now you can check following example where I have derived one child class SmallBox from a parent class Box.
Following example is similar to above example and here width member will be accessible by any member function of its derived class SmallBox.
#include <iostream>
using namespace std;
class Box {
protected:
double width;
};
class SmallBox:Box { // SmallBox is the derived class.
public:
void setSmallWidth( double wid );
double getSmallWidth( void );
};
// Member functions of child class
double SmallBox::getSmallWidth(void) {
return width ;
}
void SmallBox::setSmallWidth( double wid ) {
width = wid;
}
// Main function for the program
int main() {
SmallBox box;
// set box width using member function
box.setSmallWidth(5.0);
cout << "Width of box : "<< box.getSmallWidth() << endl;
return 0;
}
When the above code is compiled and executed, it produces the following result −
Width of box : 5
Key takeaway
A member function of a class is a function that has its definition or its prototype within the class definition like any other variable. It operates on any object of the class of which it is a member, and has access to all the members of a class for that object.
A member function of a class is a function that has its definition or its prototype within the class definition like any other variable. It operates on any object of the class of which it is a member, and has access to all the members of a class for that object.
Let us take previously defined class to access the members of the class using a member function instead of directly accessing them −
class Box {
public:
double length; // Length of a box
double breadth; // Breadth of a box
double height; // Height of a box
double getVolume(void);// Returns box volume
};
Member functions can be defined within the class definition or separately using scope resolution operator, : −. Defining a member function within the class definition declares the function inline, even if you do not use the inline specifier. So either you can define Volume() function as below −
class Box {
public:
double length; // Length of a box
double breadth; // Breadth of a box
double height; // Height of a box
double getVolume(void) {
return length * breadth * height;
}
};
If you like, you can define the same function outside the class using the scope resolution operator (::) as follows −
double Box::getVolume(void) {
return length * breadth * height;
}
Here, only important point is that you would have to use class name just before :: operator. A member function will be called using a dot operator (.) on a object where it will manipulate data related to that object only as follows −
Box myBox; // Create an object
myBox.getVolume(); // Call member function for the object
Let us put above concepts to set and get the value of different class members in a class −
#include <iostream>
using namespace std;
class Box {
public:
double length; // Length of a box
double breadth; // Breadth of a box
double height; // Height of a box
// Member functions declaration
double getVolume(void);
void setLength( double len );
void setBreadth( double bre );
void setHeight( double hei );
};
// Member functions definitions
double Box::getVolume(void) {
return length * breadth * height;
}
void Box::setLength( double len ) {
length = len;
}
void Box::setBreadth( double bre ) {
breadth = bre;
}
void Box::setHeight( double hei ) {
height = hei;
}
// Main function for the program
int main() {
Box Box1; // Declare Box1 of type Box
Box Box2; // Declare Box2 of type Box
double volume = 0.0; // Store the volume of a box here
// box 1 specification
Box1.setLength(6.0);
Box1.setBreadth(7.0);
Box1.setHeight(5.0);
// box 2 specification
Box2.setLength(12.0);
Box2.setBreadth(13.0);
Box2.setHeight(10.0);
// volume of box 1
volume = Box1.getVolume();
cout << "Volume of Box1 : " << volume <<endl;
// volume of box 2
volume = Box2.getVolume();
cout << "Volume of Box2 : " << volume <<endl;
return 0;
}
When the above code is compiled and executed, it produces the following result −
Volume of Box1 : 210
Volume of Box2 : 1560
Key takeaway
A member function of a class is a function that has its definition or its prototype within the class definition like any other variable. It operates on any object of the class of which it is a member, and has access to all the members of a class for that object.
There are four ways of passing objects to functions. Let's assume you have a class X and want to pass it to a function fun, then
This creates a shallow local copy of the object in the function scope. Things you modify here won't be reflected in the object passed to it. For example,
void fun(X x);
X x;
fun(x);
This passes a reference to the object to the function. Things you modify here will be reflected in the object passed to it. No copy of the object is created. For example,
void fun(X &x);
X x;
fun(x);
This passes a const reference to the object to the function. You cannot modify/reassign the object here directly(you can use its methods that do so though). This is useful if you want the function to have only a readonly copy of the object. No copy of the object is created. For example,
void fun(X const *x);
X x;
fun(&x);
This passes a const pointer to the object to the function. You cannot modify/reassign the pointer here. This is useful if you want the function to have only the address of this object in the pointer. No copy of object is created. For example,
void fun(X *x);
X x;
fun(&x);
This passes a pointer to the object to the function. This is similar to passing a reference to the object. No copy of object is created. For example,
<void fun(X *x);>
X x;
fun(&x);
Key takeaway
There are four ways of passing objects to functions. Let's assume you have a class X and want to pass it to a function fun, then
This creates a shallow local copy of the object in the function scope. Things you modify here won't be reflected in the object passed to it. For example,
void fun(X x);
X x;
fun(x);
This passes a reference to the object to the function. Things you modify here will be reflected in the object passed to it. No copy of the object is created. For example,
void fun(X &x);
X x;
fun(x);
A class declared inside a function is known as a local class in C++ as it is local to that function.
An example of a local class is given as follows.
#include<iostream>
using namespace std;
void func() {
class LocalClass {
};
}
int main() {
return 0;
}
In the above example, func() is a function and class LocalClass is defined inside the function. So, it is known as a local class.
A local class name can only be used in its function and not outside it. Also, the methods of a local class must be defined inside it only. A local class cannot have static data members but it can have static functions.
A program that demonstrates a local class in C++ is given as follows.
#include<iostream>
using namespace std;
void func() {
class LocalClass {
private:
int num;
public:
void getdata( int n) {
num = n;
}
void putdata() {
cout<<"The number is "<<num;
}
};
LocalClass obj;
obj.getdata(7);
obj.putdata();
}
int main() {
cout<<"Demonstration of a local class"<<endl;
func();
return 0;
}
Demonstration of a local class
The number is 7
In the above program, the class LocalClass is declared in the function func() so it is a local class. The class a variable num and two member functions that initialize and display num. After the creation of the class, its object obj is defined in the function func() and getdata() and putdata() are called using obj. This is seen as follows.
void func() {
class LocalClass {
private:
int num;
public:
void getdata( int n) {
num = n;
}
void putdata() {
cout<<"The number is "<<num;
}
};
LocalClass obj;
obj.getdata(7);
obj.putdata();
}
In the function main(), the function func() is called. This is shown below.
cout<<"Demonstration of a local class"<<endl;
func();
A nested class is a class that is declared in another class. The nested class is also a member variable of the enclosing class and has the same access rights as the other members. However, the member functions of the enclosing class have no special access to the members of a nested class.
A program that demonstrates nested classes in C++ is as follows.
#include<iostream>
using namespace std;
class A {
public:
class B {
private:
int num;
public:
void getdata(int n) {
num = n;
}
void putdata() {
cout<<"The number is "<<num;
}
};
};
int main() {
cout<<"Nested classes in C++"<< endl;
A :: B obj;
obj.getdata(9);
obj.putdata();
return 0;
}
Nested classes in C++
The number is 9
In the above program, class B is defined inside the class A so it is a nested class. The class B contains a private variable num and two public functions getdata() and putdata(). The function getdata() takes the data and the function putdata() displays the data. This is given as follows.
class A {
public:
class B {
private:
int num;
public:
void getdata(int n) {
num = n;
}
void putdata() {
cout<<"The number is "<<num;
}
};
};
In the function main(), an object of the class A and class B is defined. Then the functions getdata() and putdata() are called using the variable obj. This is shown below.
cout<<"Nested classes in C++"<< endl;
A :: B obj;
obj.getdata(9);
obj.putdata();
Key takeaway
A class declared inside a function is known as a local class in C++ as it is local to that function.
A nested class is a class that is declared in another class. The nested class is also a member variable of the enclosing class and has the same access rights as the other members. However, the member functions of the enclosing class have no special access to the members of a nested class.
If a function is defined as a friend function in C++, then the protected and private data of a class can be accessed using the function.
By using the keyword friend compiler knows the given function is a friend function.
For accessing the data, the declaration of a friend function should be done inside the body of a class starting with the keyword friend.
Declaration of friend function in C++
- class class_name
- {
- friend data_type function_name(argument/s); // syntax of friend function.
- };
In the above declaration, the friend function is preceded by the keyword friend. The function can be defined anywhere in the program like a normal C++ function. The function definition does not use either the keyword friend or scope resolution operator.
Characteristics of a Friend function:
- The function is not in the scope of the class to which it has been declared as a friend.
- It cannot be called using the object as it is not in the scope of that class.
- It can be invoked like a normal function without using the object.
- It cannot access the member names directly and has to use an object name and dot membership operator with the member name.
- It can be declared either in the private or the public part.
Let's see the simple example of C++ friend function used to print the length of a box.
- #include <iostream>
- using namespace std;
- class Box
- {
- private:
- int length;
- public:
- Box(): length(0) { }
- friend int printLength(Box); //friend function
- };
- int printLength(Box b)
- {
- b.length += 10;
- return b.length;
- }
- int main()
- {
- Box b;
- cout<<"Length of box: "<< printLength(b)<<endl;
- return 0;
- }
Output:
Length of box: 10
Let's see a simple example when the function is friendly to two classes.
- #include <iostream>
- using namespace std;
- class B; // forward declarartion.
- class A
- {
- int x;
- public:
- void setdata(int i)
- {
- x=i;
- }
- friend void min(A,B); // friend function.
- };
- class B
- {
- int y;
- public:
- void setdata(int i)
- {
- y=i;
- }
- friend void min(A,B); // friend function
- };
- void min(A a,B b)
- {
- if(a.x<=b.y)
- std::cout << a.x << std::endl;
- else
- std::cout << b.y << std::endl;
- }
- int main()
- {
- A a;
- B b;
- a.setdata(10);
- b.setdata(20);
- min(a,b);
- return 0;
- }
Output:
10
In the above example, min() function is friendly to two classes, i.e., the min() function can access the private members of both the classes A and B.
A friend class can access both private and protected members of the class in which it has been declared as friend.
Let's see a simple example of a friend class.
- #include <iostream>
- using namespace std;
- class A
- {
- int x =5;
- friend class B; // friend class.
- };
- class B
- {
- public:
- void display(A &a)
- {
- cout<<"value of x is : "<<a.x;
- }
- };
- int main()
- {
- A a;
- B b;
- b.display(a);
- return 0;
- }
Output:
value of x is : 5
In the above example, class B is declared as a friend inside the class A. Therefore, B is a friend of class A. Class B can access the private members of class A.
Key takeaway
If a function is defined as a friend function in C++, then the protected and private data of a class can be accessed using the function.
By using the keyword friend compiler knows the given function is a friend function.
For accessing the data, the declaration of a friend function should be done inside the body of a class starting with the keyword friend.
REFERENCE
1 Object-Oriented Programming with C++ by E. Balaguruswamy. (Tata McGraw-Hill) 6th Edition and onwards
2. Object oriented Programming with C++- by SouravSahay (Oxford) 2ndedition