3.5 Pure Virtual Functions and File Handling

This section introduces pure virtual functions, dynamic binding, and the fundamentals of file input/output operations using C++. The concept of stream classes is also explained to help manage file operations effectively.


1. Pure Virtual Functions

A pure virtual function is a function declared within a base class that has no definition relative to the base class. It enforces the concept of abstraction and makes a class abstract.

  • A pure virtual function is declared using the syntax:

    virtual return_type function_name() = 0;
  • Any class containing at least one pure virtual function is called an abstract class, and objects of such classes cannot be instantiated.

Example: Pure virtual function and dynamic binding.

#include <iostream>
using namespace std;

// Abstract base class
class Shape {
public:
    virtual void draw() = 0; // Pure virtual function
};

class Circle : public Shape {
public:
    void draw() override {
        cout << "Drawing a Circle" << endl;
    }
};

class Rectangle : public Shape {
public:
    void draw() override {
        cout << "Drawing a Rectangle" << endl;
    }
};

int main() {
    Shape* shape1 = new Circle();
    Shape* shape2 = new Rectangle();

    shape1->draw(); // Output: Drawing a Circle (Dynamic Binding)
    shape2->draw(); // Output: Drawing a Rectangle (Dynamic Binding)

    delete shape1;
    delete shape2;
    return 0;
}

2. Dynamic Binding

Dynamic binding ensures that the correct method is called for a derived class object when the object is accessed through a pointer or reference to the base class. This is achieved using virtual functions.

  • It allows runtime polymorphism.

  • Ensures that the appropriate overridden function is called for an object.


3. File Input/Output Operations

C++ provides the <fstream> library for file handling. The key classes for file I/O are:

  • ifstream: For input (reading from a file).

  • ofstream: For output (writing to a file).

  • fstream: For both input and output.

File Write Example

#include <iostream>
#include <ofstream> // File stream library
using namespace std;

int main() {
    ofstream outFile("example.txt"); // Open file for writing
    if (!outFile) {
        cout << "Error opening file!" << endl;
        return 1;
    }

    outFile << "Hello, File Handling in C++!" << endl;
    outFile << "This is a test file." << endl;

    outFile.close(); // Close file after writing
    cout << "Data written to file successfully!" << endl;

    return 0;
}

The file contains:

Hello, File Handling in C++!
This is a test file.

File Read Example

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

int main() {
    ifstream inFile("example.txt"); // Open file for reading
    if (!inFile) {
        cout << "Error opening file!" << endl;
        return 1;
    }

    string line;
    while (getline(inFile, line)) { // Read line by line
        cout << line << endl;
    }

    inFile.close(); // Close file after reading
    return 0;
}

The file contains:

Hello, File Handling in C++!
This is a test file.

File Append Example

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

int main() {
    ofstream outFile("example.txt", ios::app); // Open file in append mode
    if (!outFile) {
        cout << "Error opening file!" << endl;
        return 1;
    }

    outFile << "Appending more data to the file." << endl;

    outFile.close();
    cout << "Data appended successfully!" << endl;

    return 0;
}

The file now contains:

Hello, File Handling in C++!
This is a test file.
Appending more data to the file.

4. Stream Class Hierarchy

C++ provides a hierarchy of stream classes to manage input and output operations:

ios_base
   |
   +--> ios
         |
         +--> istream (input stream)
         |      |
         |      +--> ifstream (file input stream)
         |
         +--> ostream (output stream)
                |
                +--> ofstream (file output stream)
                |
                +--> iostream (input/output stream)
                       |
                       +--> fstream (file input/output stream)

Conclusion

  • Pure Virtual Functions:

    • Declared with = 0 in the base class.

    • Makes a class abstract and ensures derived classes implement specific functionality.

  • Dynamic Binding: Ensures runtime polymorphism through virtual functions.

  • File Handling:

    • ifstream, ofstream, and fstream are key classes for file I/O.

    • Files can be opened in modes such as ios::in, ios::out, or ios::app.

  • Stream Class Hierarchy: Defines how different streams (standard and file-based) interact.

Last updated