C++ Program for Opaque Pointer

26/05/2024 0 By indiafreenotes

Opaque pointers (or opaque types) in C++ are used to hide the implementation details of a data structure from the users of the interface. This technique is often used to achieve data encapsulation and information hiding, which are important principles of object-oriented programming. The main advantage of using opaque pointers is to provide a clear separation between the interface and the implementation, which leads to better modularity and maintainability of code.

Key Concepts

  • Definition and Usage

An opaque pointer is a pointer to a data structure whose definition is hidden from the user. The user interacts with the pointer through a defined interface without needing to know the internal details of the data structure.

  • Implementation

Typically involves defining an incomplete type in the public header and the complete type in the implementation file.

Let’s create a program to demonstrate the use of opaque pointers in C++. We will create a ‘Rectangle’ class with its implementation details hidden using an opaque pointer.

File: ‘Rectangle.h’ (Public Header)

#ifndef RECTANGLE_H

#define RECTANGLE_H

// Forward declaration of the RectangleImpl struct

struct RectangleImpl;

class Rectangle {

public:

    // Constructor

    Rectangle(int length, int width);

    // Destructor

    ~Rectangle();

    // Member function to set dimensions

    void setDimensions(int length, int width);

    // Member function to calculate area

    int area() const;

    // Member function to print dimensions

    void printDimensions() const;

private:

    RectangleImpl* pImpl; // Opaque pointer to implementation

};

#endif // RECTANGLE_H

File: ‘Rectangle.cpp’ (Implementation)

#include <iostream>

#include “Rectangle.h”

using namespace std;

// Definition of the RectangleImpl struct

struct RectangleImpl {

    int length;

    int width;

    RectangleImpl(int l, int w) : length(l), width(w) {}

};

Rectangle::Rectangle(int length, int width)

    : pImpl(new RectangleImpl(length, width)) {}

Rectangle::~Rectangle() {

    delete pImpl;

}

void Rectangle::setDimensions(int length, int width) {

    pImpl->length = length;

    pImpl->width = width;

}

int Rectangle::area() const {

    return pImpl->length * pImpl->width;

}

void Rectangle::printDimensions() const {

    cout << “Length: ” << pImpl->length << “, Width: ” << pImpl->width << endl;

}

File: ‘main.cpp’ (Client Code)

#include “Rectangle.h”

int main() {

    // Create an object of Rectangle using the constructor

    Rectangle rect(10, 5);

    rect.printDimensions();

    // Set new dimensions

    rect.setDimensions(15, 10);

    rect.printDimensions();

    // Calculate and print the area

    cout << “Area: ” << rect.area() << endl;

    return 0;

}

Explanation of the Program

Public Header (‘Rectangle.h’)

  • Forward Declaration: Forward declares the ‘RectangleImpl’ struct, making it known to the ‘Rectangle’ class without revealing its implementation.
  • Rectangle Class: The ‘Rectangle’ class contains a private member ‘pImpl’, which is a pointer to ‘RectangleImpl’.

Implementation File (‘Rectangle.cpp’)

Defines the actual structure of ‘RectangleImpl’, which contains the ‘length’ and ‘width’

  • Constructor and Destructor: The constructor initializes ‘pImpl’ by creating a new ‘RectangleImpl’ object, and the destructor deletes ‘pImpl’ to free the allocated memory.
  • Member Functions: These functions manipulate the ‘RectangleImpl’ object through the opaque pointer ‘pImpl’.

Client Code (‘main.cpp’)

The client code interacts with the ‘Rectangle’ class without needing to know about ‘RectangleImpl’. The client can create a ‘Rectangle’ object, set its dimensions, and calculate its area using the public interface.