C++ Programming Language
--
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.
Introduction
C++ is a statically typed, compiled, general-purpose, case-sensitive, free-form programming language that supports procedural, object-oriented, and generic programming.
C++ is regarded as a middle-level language, as it comprises a combination of both high-level and low-level language features.
A Simple Program Example
- The C++ language defines several headers, which contain information that is either necessary or useful to your program. For this program, the header <iostream> is needed.
- The line using namespace std; tells the compiler to use the std namespace. Namespaces are a relatively recent addition to C++.
- The line int main() is the main function where program execution begins.
- The next line cout << “Hello World”; causes the message “Hello World” to be displayed on the screen.
- The next line return 0; terminates main( ) function and causes it to return the value 0 to the calling process.
Save the file as: hello.cpp
Command to compile the program
$ g++ hello.cpp
$ ./a.out
Hello World
NameSpaces
Namespacing does for functions and classes what scope does for variables. It allows you to use the same function or class name in different parts of the same program without causing a name collision.
In simple terms, think of a namespace as a person’s surname. If there are two people named “John” you can use their surnames to tell them apart.
The Scenario
Suppose you write an application that uses a function named output()
. Your output()
function takes all of the HTML code on your page and sends it to the user.
Later on your application gets bigger and you want to add new features. You add a library that allows you to generate RSS feeds. This library also uses a function named output()
to output the final feed.
When you call output()
, how does PHP know whether to use your output()
function or the RSS library's output()
function? It doesn't. Unless you're using namespaces.
How do we solve having two output()
functions? Simple. We stick each output()
function in its own namespace.
That would look something like this:
namespace MyProject;function output() {
# Output HTML page
echo 'HTML!';
}namespace RSSLibrary;function output(){
# Output RSS feed
echo 'RSS!';
}
we can declare that we’re in one of the namespaces and then we can just call that namespace’s output()
:
namespace MyProject;output(); # Output HTML page
\RSSLibrary\output();
Primitive Built-in Types
C++ offers a rich assortment of built-in as well as user defined data types. Following table lists down seven basic C++ data types −
Typedef Declarations
You can create a new name for an existing type using typedef.
Following is the simple syntax to define a new type using typedef −
typedef type newname;
For example, the following tells the compiler that feet is another name for int
typedef int feet;
Now, the following declaration is perfectly legal and creates an integer variable called distance −
feet distance;
Enumerated Types
An enumerated type declares an optional type name and a set of zero or more identifiers that can be used as values of the type. Each enumerator is a constant whose type is the enumeration.
Creating an enumeration requires the use of the keyword enum. The general form of an enumeration type is −
enum enum-name { list of names } var-list;
Here, the enum-name is the enumeration’s type name. The list of names is comma separated.
For example, the following code defines an enumeration of colors called color and the variable c of type color. Finally, c is assigned the value “blue”.
enum color { red, green, blue } c;
c = blue;
Variable Declaration
#include <iostream>
using namespace std;
// Variable declaration:
extern int a, b;
extern int c;
extern float f;
int main () {
// Variable definition:
int a, b;
int c;
float f;
// actual initialization
a = 10;
b = 20;
c = a + b;
cout << c << endl ;
f = 70.0/3.0;
cout << f << endl ;
return 0;
}
Defining Constant
There are two simple ways in C++ to define constants −
- Using #define preprocessor.
#define identifier value
- Using const keyword.
const type variable = value;
Modifiers in front of data types
C++ allows the char, int, and double data types to have modifiers preceding them. A modifier is used to alter the meaning of the base type so that it more precisely fits the needs of various situations.
The data type modifiers are listed here −
- signed
- unsigned
- long
- short
Storage Class
A storage class defines the scope (visibility) and life-time of variables and/or functions within a C++ Program. These specifiers precede the type that they modify. There are following storage classes, which can be used in a C++ Program.
- auto
- register
- static
- extern
- mutable
The auto Storage Class
The auto storage class is the default storage class for all local variables.
{
int mount;
auto int month;
}
The example above defines two variables with the same storage class, auto can only be used within functions, i.e., local variables.
The register Storage Class
The register storage class is used to define local variables that should be stored in a register instead of RAM. This means that the variable has a maximum size equal to the register size (usually one word) and can’t have the unary ‘&’ operator applied to it (as it does not have a memory location).
{
register int miles;
}
The register should only be used for variables that require quick access such as counters. It should also be noted that defining ‘register’ does not mean that the variable will be stored in a register. It means that it MIGHT be stored in a register depending on hardware and implementation restrictions.
The static Storage Class
The static storage class instructs the compiler to keep a local variable in existence during the life-time of the program instead of creating and destroying it each time it comes into and goes out of scope. Therefore, making local variables static allows them to maintain their values between function calls.
The static modifier may also be applied to global variables. When this is done, it causes that variable’s scope to be restricted to the file in which it is declared.
In C++, when static is used on a class data member, it causes only one copy of that member to be shared by all objects of its class.
#include <iostream>
// Function declaration
void func(void);
static int count = 10; /* Global variable */
main() {
while(count--) {
func();
}
return 0;
}// Function definition
void func( void ) {
static int i = 5; // local static variable
i++;
std::cout << "i is " << i ;
std::cout << " and count is " << count << std::endl;
}
The extern Storage Class
The extern storage class is used to give a reference of a global variable that is visible to ALL the program files. When you use ‘extern’ the variable cannot be initialised as all it does is point the variable name at a storage location that has been previously defined.
When you have multiple files and you define a global variable or function, which will be used in other files also, then extern will be used in another file to give reference of defined variable or function. Just for understanding extern is used to declare a global variable or function in another file.
The extern modifier is most commonly used when there are two or more files sharing the same global variables or functions as explained below.
To use extern
:
- Declare the variable or function in a header file: Create a header file (e.g.,
myheader.h
) and declare the variable or function using theextern
keyword. This informs the compiler that the definition of the variable or function exists elsewhere.
// myheader.h
extern int myVariable;
extern void myFunction();
2. Define the variable or function in a source file: In a separate source file (e.g., mycode.cpp
), define the variable or function that was declared with extern
. This provides the actual implementation or storage for the variable or function.
// mycode.cpp
int myVariable = 42;
void myFunction() {
// Function implementation
}
3. Include the header file: In any source file where you want to use the global variable or function, include the header file that declares it.
// main.cpp
#include "myheader.h"
#include <iostream>
int main() {
std::cout << myVariable << std::endl;
myFunction();
return 0;
}
By declaring the variable or function as extern
in the header file, you indicate to the compiler that its definition is located elsewhere. The actual definition is provided in the corresponding source file. When you include the header file in other source files, the declarations inform the compiler about the existence and type of the variable or function, allowing you to use it in your code.
Using extern
allows you to separate the declaration and definition of global variables and functions, promoting modular programming and reusability across multiple source files or translation units.
The mutable Storage Class
The mutable specifier applies only to class objects, which are discussed later in this tutorial. It allows a member of an object to override const member function. That is, a mutable member can be modified by a const member function.
Operators in C++
An operator is a symbol that tells the compiler to perform specific mathematical or logical manipulations.
- Arithmetic Operators
- Relational Operators
- Logical Operators
- Bitwise Operators
- Assignment Operators
- Misc Operators
Arithmetic Operators
Relational Operators
Logical Operators
Bitwise Operators
Assignment Operators
Misc Operators
Loop
While
Do…While
For
break;
continue;
goto;
Decision Making
Functions
Function Declarations tells the compiler about a function name and how to call the function. The actual body of the function can be defined separately.
Data Structure
Array
Declaring Arrays: type arrayName[ arraySize]
for eg, double balance[10]
double balance[5] = {1000.0, 2.0, 3.4, 17.0, 50.0};int bax[5] = {};
Char [ ]
This string is actually a one-dimensional array of characters which is terminated by a null character ‘\0’. Thus a null-terminated string contains the characters that comprise the string followed by a null.\
String Class supports all the operations mentioned above, additionally much more functionality.
Pointers
Every variable is a memory location and every memory location has its address defined which can be accessed using ampersand (&) operator which denotes an address in memory.
A pointer is a variable whose value is the address of another variable.
The general form of a pointer variable declaration is −
type *var-name;int *ip; // pointer to an integer
double *dp; // pointer to a double
float *fp; // pointer to a float
char *ch // pointer to character
The actual data type of the value of all pointers, whether integer, float, character, or otherwise, is the same, a long hexadecimal number that represents a memory address. The only difference between pointers of different data types is the data type of the variable or constant that the pointer points to.
Null Pointers
Pointer arithmetic
ptr++
points to the next location.
We might prefer using a pointer instead of an array because the variable pointer can be incremented, unlike the array name which cannot be incremented because it is a constant.
Array of Pointers
We might want to maintain an array which can store pointers to an int or char or any data type.
int *ptrArr[5]
Each element in ptrArr now holds a pointer to an int value.
Data Structures
C/C++ arrays allow you to define variables that combine several data items of the same kind, but structure is another user defined data type which allows you to combine data items of different kinds.
To define a structure, you must use the struct statement. The struct statement defines a new data type, with more than one member, for your program. The format of the struct statement is this.
struct Books {
char title[50];
char author[50];
char subject[100];
int book_id;
} book;
To access any member of a structure, we use the member access operator (.).
You can define pointers to structures in very similar way as you define pointer to any other variable as follows −
struct Books *struct_pointer;
Now, you can store the address of a structure variable in the above defined pointer variable. To find the address of a structure variable, place the & operator before the structure’s name as follows −
struct_pointer = &Book1;
To access the members of a structure using a pointer to that structure, you must use the -> operator as follows −
struct_pointer->title;
The typedef keyword
There is an easier way to define structs or you could “alias” types you create. For example −
typedef struct {
char title[50];
char author[50];
char subject[100];
int book_id;
} Books;
C++ Object Oriented Programming
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.
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.
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
Class Member Function
A member function of a class is a function that has its definition or its prototype within the class definition like any other variable.
Member functions can be defined within the class definition or separately using scope resolution operator, : −.
Method 1:
Method 2:
Class Access Modifiers
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 −
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.
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.
Constructor Class
A class constructor is a special member function of a class that is executed whenever we create new objects of that class.
A destructor is a special member function of a class that is executed whenever an object of it’s class goes out of scope or whenever the delete expression is applied to a pointer to the object of that class.
A destructor will have exact same name as the class prefixed with a tilde (~) and it can neither return a value nor can it take any parameters. Destructor can be very useful for releasing resources before coming out of the program like closing files, releasing memories etc.
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.
The most common form of copy constructor is shown here −
classname (const classname &obj) {
// body of constructor
}
Here, obj is a reference to an object that is being used to initialize another object.
Friend Functions
A friend function of a class is defined outside that class’ scope but it has the right to access all private and protected members of the class. Even though the prototypes for friend functions appear in the class definition, friends are not member functions.
A friend can be a function, function template, or member function, or a class or class template, in which case the entire class and all of its members are friends.
To declare a function as a friend of a class, precede the function prototype in the class definition with keyword friend as follows −
class Box {
double width;
public:
double length;
friend void printWidth( Box box );
void setWidth( double wid );
};
To declare all member functions of class ClassTwo as friends of class ClassOne, place a following declaration in the definition of class ClassOne −
class MyClass {
private:
int privateData;public:
MyClass() : privateData(0) {} friend class FriendClass;
};class FriendClass {
public:
void accessPrivateData(MyClass& obj) {
obj.privateData = 42; // Accessing the private member of MyClass
}
};int main() {
MyClass obj;
FriendClass friendObj; friendObj.accessPrivateData(obj); return 0;
}// Helpful for when implementing helper classes, operator overloading, or providing access to internals for testing purposes.
Here are some situations where friend functions can be beneficial:
- Accessing private members: Friend functions can access private members of a class, allowing them to manipulate or retrieve data that would otherwise be inaccessible from outside the class. This can be useful when you want to provide specific functions or operations that require access to private implementation details.
- Operator overloading: Friend functions are commonly used in operator overloading. For example, if you want to overload the addition operator (
+
) to work with objects of your class, you can define a friend function that performs the addition operation and has access to the private members of the class. - Providing utility functions: Friend functions can be used to provide utility functions that are closely related to a class but do not necessarily need to be members of the class. These functions can access private members and provide additional functionality that complements the class.
- Improving encapsulation: Friend functions can sometimes be used to improve encapsulation by allowing controlled access to internal implementation details. They provide a way to selectively grant access to certain functions without exposing all the implementation details as public members.
It’s important to note that the use of friend functions should be limited and carefully considered. While they can provide additional flexibility, they can also break encapsulation and increase coupling between classes. It’s generally recommended to use member functions and appropriate access modifiers (public, private, protected) to encapsulate behavior and data within a class, and resort to friend functions only when necessary and well-justified.
C++ Inline function
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.
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.
The distinction between normal functions and inline functions is the different compilation process for them.
After writing any program, it is first compiled to get an executable code. Which is then executed, the OS loads the instructions into the computer’s memory, so that each instruction is stored in a specific memory location. When a function call instruction is encountered, the compiler stores the memory address of the instruction immediately following the function call statement, loads the function being called into the memory, copies argument values, jumps to the memory location of the called function, executes the function code, stores the return value of the function, and then jumps back to the address of the instruction that was saved just before executing the called function.
The C++ inline function provides an alternative. With inline code, the compiler replaces the function call statement with the function code itself (this process is called expansion) and then compiles the entire code. Thus, with this the compiler doesn’t have to do the long, time consuming process of jumping to the function. It saves on the overheads of a function call as it’s not invoked, rather its code is replaced in the program.
Another explanation:
The purpose of using inline functions is to improve the performance of the program by reducing the overhead of function calls. Instead of the usual process of pushing arguments onto the stack, transferring control to the function, and returning back, an inline function is expanded at the call site, eliminating the function call overhead. This can lead to faster execution as it avoids the cost of function call setup and teardown.
this pointer
Every object in C++ has access to its own address through an important pointer called this pointer. The this pointer is an implicit parameter to all member functions. Therefore, inside a member function, this may be used to refer to the invoking object.
Friend functions do not have a this pointer, because friends are not members of a class. Only member functions have a this pointer.
Pointer to Classes
A pointer to a C++ class is done exactly the same way as a pointer to a structure and to access members of a pointer to a class you use the member access operator -> operator, just as you do with pointers to structures. Also as with all pointers, you must initialize the pointer before using it.
Static Members of a class
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 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.
If you want to have a function that deals with the static member, that function has to be declared static too.
Inheritance
Inheritance allows us to define a class in terms of another class, which makes it easier to create and maintain an application.
When creating a class, instead of writing completely new data members and member functions, the programmer can designate that the new class should inherit the members of an existing class. This existing class is called the base class, and the new class is referred to as the derived class.
The idea of inheritance implements the is a relationship. For example, mammal IS-A animal, dog IS-A mammal hence dog IS-A animal as well and so on.
A class can be derived from more than one classes, which means it can inherit data and functions from multiple base classes.
To define a derived class, we use a class derivation list to specify the base class(es). A class derivation list names one or more base classes and has the form −
class derived-class: access-specifier base-class
Consider a base class Shape and its derived class Rectangle as follows −
Another Example:
A derived class can access all the non-private members of its base class.
Overloading (Operator and Function)
C++ allows you to specify more than one definition for a function name or an operator in the same scope, which is called function overloading and operator overloading respectively.
Function overloading -> Different number of arguments or types for the same function name.
Operator overloading -> Overloaded operators are functions with special names: the keyword “operator” followed by the symbol for the operator being defined. Like any other function, an overloaded operator has a return type and a parameter list.
Box operator+(const Box&);
declares the addition operator that can be used to add two Box objects and returns final Box object. Most overloaded operators may be defined as ordinary non-member functions or as class member functions. In case we define above function as non-member function of a class then we would have to pass two arguments for each operand as follows −
Box operator+(const Box&, const Box&);
Polymorphism
The word polymorphism means having many forms. Typically, polymorphism occurs when there is a hierarchy of classes and they are related by inheritance.
C++ polymorphism means that a call to a member function will cause a different function to be executed depending on the type of object that invokes the function.
The reason for the incorrect output is that the call of the function area() is being set once by the compiler as the version defined in the base class. This is called static resolution of the function call, or static linkage — the function call is fixed before the program is executed. This is also sometimes called early binding because the area() function is set during the compilation of the program.
But now, let’s make a slight modification in our program and precede the declaration of area() in the Shape class with the keyword virtual so that it looks like this −
This time, the compiler looks at the contents of the pointer instead of it’s type.
virtual function is a function in a base class that is declared using the keyword virtual. Defining in a base class a virtual function, with another version in a derived class, signals to the compiler that we don’t want static linkage for this function.
Interfaces
An interface describes the behavior or capabilities of a C++ class without committing to a particular implementation of that class.
The C++ interfaces are implemented using abstract classes. A class is made abstract by declaring at least one of its functions as pure virtual function. A pure virtual function is specified by placing “= 0” in its declaration as follows −