C++ Programming Examples: File Handling, Operator Overloading, and More
Write a C++ Program to Write Contents to a File
#include <iostream> #include <stdio.h> #include <fstream> #include <string.h> using namespace std; int main() { char fname[20], str[200]; fstream fp; cout << "Enter the Name of File: "; gets(fname); fp.open(fname, fstream::out); if(!fp) { cout << "\nError Occurred!"; return 0; } cout << "Enter the Data: "; gets(str); while(strlen(str) > 0) { fp << str; fp << "\n"; gets(str); } fp.close(); cout << endl; return 0; }
Write a C++ Program for Binary Operator Overloading for Addition of Two Complex Numbers
#include <iostream> using namespace std; class Complex { private: float real; float imag; public: Complex(float real, float imag) { this->real = real; this->imag = imag; } Complex operator+(const Complex& other) { Complex result; result.real = this->real + other.real; result.imag = this->imag + other.imag; return result; } void print() { cout << "(" << this->real << ", " << this->imag << ")" << endl; } }; int main() { Complex c1(1, 2); Complex c2(3, 4); Complex c3 = c1 + c2; c1.print(); c2.print(); c3.print(); return 0; }
OUTPUT
(1, 2)
(3, 4)
(4, 6)
Explain Function Template Overloading with a C++ Program
Function template overloading is a feature of C++ that allows you to have multiple functions with the same name, but with different parameter types. This can be useful for providing different implementations of a function for different data types.
template <typename T> T add(T a, T b) { return a + b; } int main() { int x = 1; int y = 2; float a = 1.5; float b = 2.5; // Add two integers int sum1 = add(x, y); std::cout << sum1 << std::endl; // prints 3 // Add two floats float sum2 = add(a, b); std::cout << sum2 << std::endl; // prints 4 return 0; }
In this example, the add() function template is overloaded for two different data types: int and float. The compiler will choose the correct specialization of the add() function template based on the types of the arguments that are passed to it.
Function template overloading can be a powerful tool, but it can also be confusing if used incorrectly. It is important to make sure that the different specializations of a function template are actually different, and that they can be used correctly.
Illustrate the ‘this’ Pointer with a C++ Program
In C++, the this pointer is used to represent the address of an object inside a member function. For example, consider an object obj calling one of its member functions, say method(), as obj.method(). Then, the this pointer will hold the address of object obj inside the member function method(). The this pointer acts as an implicit argument to all member functions.
class MyClass { public: int x; MyClass(int x) { this->x = x; } void print() { cout << x << endl; } }; int main() { MyClass myClass(10); myClass.print(); // prints 10 return 0; }
In this example, the this pointer is used to access the x data member of the MyClass object. The this pointer is implicitly passed to all member functions of a class. This allows you to access the members of the current object within a class’s member function. This allows you to differentiate them from parameters or local variables with the same names. The this pointer is also used to call other member functions of the current object. For example, you could use the this pointer to call the print() function from within the print() function. This would allow you to print the value of the x data member multiple times.
Data Type Conversion in C++
User-defined data types are designed by the user to suit their requirements. The compiler does not support automatic type conversions for such data types; therefore, the user needs to design the conversion routines themselves if required.
There can be three types of situations that may come up in data conversion between incompatible data types:
Conversion of Primitive Data Type to User-Defined Type
To perform this conversion, the idea is to use the constructor to perform type conversion during object creation. Below is an example to convert int to a user-defined data type:
#include <iostream> using namespace std; class Point { public: int x; int y; Point(int x, int y) { this->x = x; this->y = y; } }; int main() { // Create a primitive data type variable int a = 10; // Convert the primitive data type variable to a user-defined type variable Point p = Point(a, a); // Print the user-defined type variable cout << p.x << ", " << p.y << endl; return 0; }
OUTPUT
10, 10
Types of Inheritance in C++
There are five main types of inheritance in C++:
Single Inheritance
In single inheritance, a class can inherit from only one parent class. This is the most common and simplest type of inheritance.
Multiple Inheritance
In multiple inheritance, a class can inherit from multiple parent classes. This can be useful in some cases, but it can also lead to ambiguity and complexity.
Hierarchical Inheritance
In hierarchical inheritance, multiple child classes can be inherited from a single parent class. This is a relatively simple type of inheritance that can be useful for organizing related classes.
Multilevel Inheritance
In multilevel inheritance, a class can be inherited from a derived class. This can create a hierarchy of classes that can be useful for modeling real-world relationships.
Hybrid Inheritance
Hybrid inheritance is a combination of multiple inheritance and hierarchical inheritance. It is the most complex type of inheritance and can be difficult to understand and use.
Parameterized Constructors in C++
A constructor is a special member function of a class that is automatically called when an object of the class is created. It is used to initialize the data members of the object.
A parameterized constructor is a constructor that takes arguments during the creation of an object. Unlike a default constructor, which has no parameters, a parameterized constructor allows you to initialize the object’s properties with specific values provided as arguments.
Here is an example of a parameterized constructor in C++:
class Point { public: Point(int x, int y) { this->x = x; this->y = y; } private: int x; int y; };
Objects as Function Arguments in C++
In C++, objects can be passed as arguments to functions. This is useful when you want to pass the state of an object to a function, or when you want to modify the state of an object within a function.
There are two ways to pass objects as function arguments: by value or by reference.
When an object is passed by value, a copy of the object is made and passed to the function. This means that any changes made to the object within the function will not affect the original object.
When an object is passed by reference, the address of the object is passed to the function. This means that any changes made to the object within the function will affect the original object.
class Point { public: int x, y; }; void printPoint(Point p) { std::cout << "(" << p.x << ", " << p.y << ")" << std::endl; } int main() { Point p1 = {1, 2}; printPoint(p1); // Prints "(1, 2)" return 0; }
Friend Functions in C++
A friend function in C++ is a non-member function that can access a class’s private, protected, and public members. Friend functions are declared outside of a class but can access the class’s private and protected members.
Friend functions can be used when a class’s private data needs to be accessed directly without using an object of that class. They can also be used to perform operator overloading.
Friend functions can be useful for sharing data between different parts of a program. However, it’s important to use friend functions carefully to maintain the security and encapsulation of your code.
Advantages of Friend Functions
- Improving performance by reducing function calls and data copying
- Enhancing code readability and organization
- Simplifying testing and debugging
Disadvantages of Friend Functions
- Making access control more difficult
- Making code harder to understand
- Increasing the risk of errors and bugs
Exception Handling in C++
An exception is an object that is thrown when an error occurs during the execution of a program. Exceptions are used to handle errors gracefully and prevent the program from crashing.
Why Exception Handling is Needed
- To handle errors that occur during the execution of a program.
- To prevent the program from crashing when an error occurs.
- To provide a way to recover from errors gracefully.
- To improve the readability and maintainability of code.
Example of Exception Handling
try { // Code that might throw an exception } catch (std::exception& e) { // Handle the exception }
In this example, the try block contains the code that might throw an exception. If an exception does occur, the catch block will be executed. The catch block can handle the exception in any way that is appropriate.
Sequence Containers in C++
In C++, a sequence container is a container class template in the standard library that implements storage of data elements. Being templates, they can be used to store arbitrary elements, such as integers or custom classes.
The five sequence containers in C++ are array, vector, list, forward_list, and deque.
Array
An array is a data structure that stores a collection of items in a contiguous block of memory. Arrays are accessed using indices, which are integers that represent the position of the item in the array.
Vector
A vector is a dynamic array, which means that it can grow and shrink in size as needed. Vectors are implemented using contiguous blocks of memory, and they provide efficient random access to elements.
List
A list is a doubly linked list, which means that each element in the list contains pointers to the next and previous elements in the list. Lists are implemented using non-contiguous blocks of memory, and they provide efficient insertion and deletion of elements.
Forward_list
A forward_list is a singly linked list, which means that each element in the list contains a pointer to the next element in the list. forward_lists are implemented using non-contiguous blocks of memory, and they provide efficient insertion and deletion of elements.
Deque
A deque is a double-ended queue, which means that elements can be added and removed from both the front and back of the queue.
Manipulators in C++
Manipulators are helping functions in C++ that are used to modify the input/output stream. What this means is that they will not modify the value of a variable; they will only modify the streams or formatting streams using the insertion (<<) and extraction (>>) operators.
Key Points about Manipulators
- Manipulators are special functions that can be included in the I/O statement to alter the format parameters of a stream.
- Manipulators are operators that are used to format the data display.
- To access manipulators, the file
iomanipshould be included in the program.
Manipulators are used for enhancing streams or formatting streams. For writing data, we can adopt some formats. For example, a common manipulator that we use is endl, which is used for the endline. Instead of endl, we can also say cout << "\n"; This will also print a new line. So, endl is a manipulator that is used for formatting streams. So, it is useful for formatting output streams.
