INDUSTRIAL PROCUREMENT CATALOGUE / GROUP 06 OOPS PROJECT DEMO STORE · NO REAL PAYMENTS
F+forgesupply

INDUSTRIAL EQUIPMENT / INDIA

Industrial strength.
Built for work.

A demo B2B catalogue for factories, workshops and construction teams. Compare industrial machines, material-handling equipment, power systems and safety supplies, then build a procurement cart.

Browse equipment ↘16 INDUSTRIAL PRODUCTS · DEMO LISTINGS
16PRODUCT LISTINGS
04INDUSTRIAL CATEGORIES
01PROCUREMENT CART
Industrial engineering and manufacturing equipment
FORGESUPPLY / EQUIPMENT INDEXG6 / 2026
INDUSTRIAL PROCUREMENTMachines that
move work forward.
TOOLS · HANDLING · POWER · SAFETY
ILLUSTRATIVE CATALOGUEFIG. 01 — INDUSTRIAL SYSTEMS
✳Equipment for industry
↗Clear demo pricing in INR
◎Student-built marketplace demo

01 / INDUSTRIAL CATALOGUE

Source the right equipment.

Browse sample listings for industrial procurement. Prices and specifications are illustrative classroom data, not supplier quotations.

16PRODUCTS
IN CATALOGUE
02 / INDUSTRIAL PROCUREMENT

SPECIFICATIONS FIRST. PROCUREMENT MADE CLEAR.

The right machine
keeps work moving.

ForgeSupply is a fictional industrial marketplace concept inspired by B2B supplier catalogues. Buyers can browse machinery and industrial supplies, compare sample listings, add quantities to a cart and review an itemised estimate. Product details and prices are illustrative, not live IndiaMART listings or real quotations.

Browse equipment ↗
FS
G6 / 26

03 / THE CORE OF THE PROJECT

OOPS is the system design, not decoration.

ForgeSupply is a fictional industrial shopping-cart project. Its C++ companion program models products, cart items and a shopping cart using classes and objects. This guide explains the theory first, then shows exactly how each idea appears in cpp/shopping_cart.cpp.

01 / MODEL

Classes & objects

A Product class defines the data and behaviour common to industrial products. Each product in the catalogue is an object made from that class.

02 / PROTECT

Encapsulation

Product details and cart quantities are private. Other code interacts with them through public methods, rather than changing internal state directly.

03 / RELATE

Composition

A CartItem contains a Product, and a ShoppingCart stores cart items. These objects cooperate to model the real problem.

04 / REUSE

Generic programming

A function template searches different kinds of objects without duplicating the search algorithm. Vectors hold collections that grow as needed.

IMPORTANT DISTINCTION The browser interface is implemented in HTML, CSS and JavaScript. The OOPS implementation described in this guide is the companion C++17 program at cpp/shopping_cart.cpp. They demonstrate the same shopping-cart idea, but are not connected to each other in this version.

04 / OOPS, FROM FIRST PRINCIPLES

What object-oriented programming actually means.

Object-Oriented Programming (OOP or OOPS, Object-Oriented Programming System) is a programming approach that organises a program around objects. An object combines state (the information it holds) with behaviour (the operations it can perform). In C++, classes are the main language feature used to define these objects.

THE PROBLEM WE ARE MODELLING

An industrial shopping cart has real-world entities.

A catalogue contains products. A product has an ID, a name and a price. A cart item combines a product with a chosen quantity. A shopping cart contains several cart items and calculates a subtotal or bill. OOPS lets us represent these related entities directly instead of scattering unrelated variables and functions throughout the program.

Product→CartItem→ShoppingCart

FOUR WORDS TO REMEMBER

State
The data an object currently stores, such as a product's price or a cart item's quantity.
Behaviour
The operations an object can perform, such as returning a product ID or calculating a line total.
Class
A definition describing which data and functions objects of that type have.
Object
A particular instance of a class, with its own current state.

FOUNDATION / THE LANGUAGE OF OOPS

Classes, objects and the four pillars

These are the standard OOPS ideas worth understanding for a viva. The page distinguishes concepts that the current code demonstrates from concepts that are only explained for comparison.

01

Class and object

BLUEPRINT AND INSTANCE

Definition: A class is a user-defined type that groups data members and member functions together. An object is an instance of that class. The class describes the structure; each object stores its own values.

In ForgeSupply: Product is a class. The CNC machining centre and the MIG welding machine are two different Product objects with different IDs, names and prices.

class Product {
private:
    int id;
    string name;
    double price;
public:
    int getId() const { return id; }
};

Product cnc(1, "CNC Machining Centre", 1850000);
Product welder(4, "MIG Welding Machine", 42500);

Remember: Product is the type; cnc and welder are objects. Each object has its own member values.

02

Encapsulation

KEEP DATA AND RELATED METHODS TOGETHER

Definition: Encapsulation bundles data and the functions that operate on that data inside a class. It commonly uses access control to restrict direct access to internal state. This helps the class maintain valid values and reduces accidental misuse.

In ForgeSupply: Product keeps id, name and price private. Other code reads values through public getter functions. CartItem similarly keeps its quantity private and exposes controlled operations.

class Product {
private:
    double price;  // cannot be accessed directly from outside
public:
    double getPrice() const {
        return price;
    }
};

For example, code cannot normally write cnc.price = -500 because price is private. The constructor also rejects a negative price. These protections work together: access control restricts who can modify data, and validation rejects invalid input.

Remember: Encapsulation is not just “putting variables in a class”. It is controlling how the object's state is accessed and changed.

03

Abstraction

SHOW WHAT AN OBJECT CAN DO, HIDE HOW

Definition: Abstraction presents a simple, relevant interface while hiding unnecessary implementation details. A user of an object should be able to use its operations without needing to know every step inside them.

In ForgeSupply: A caller can use cart.printBill(0.10) to request a bill. The caller does not have to manually loop through every cart item, calculate the subtotal, calculate the discount, estimate tax and format each line. Those details are handled inside the class.

// The caller uses a clear, high-level operation:
cart.printBill(0.10);

// Internally, printBill() checks the cart,
// calculates totals and prints the itemised bill.

Abstraction and encapsulation are related but not identical. Encapsulation concerns bundling and controlling access to internals. Abstraction concerns presenting only the essential operations to the caller.

Remember: Abstraction reduces the amount of detail a user of a class needs to understand.

04

Inheritance

CREATE A SPECIALISED CLASS FROM A BASE CLASS

Definition: Inheritance allows a new class (derived class) to reuse or extend members of an existing class (base class). It is often described as an “is-a” relationship. For example, in a different design, an IndustrialProduct might be a general base class and Machine a specialised derived class.

// Illustrative example only.
// This inheritance hierarchy is NOT in the current program.
class IndustrialProduct {
public:
    string name;
};

class Machine : public IndustrialProduct {
public:
    double powerRating;
};

Project status: The current C++ implementation does not use inheritance. It models products, cart items and the cart as separate classes connected by composition. That is a deliberate description of the code as it exists, not a claim that every OOPS program must use every pillar.

Remember: Inheritance is “is-a”; composition is “has-a”. A cart has cart items, it is not a type of cart item.

05

Polymorphism

ONE INTERFACE, DIFFERENT BEHAVIOURS

Definition: Polymorphism means “many forms”: the same interface or operation can produce different behaviour depending on the type or object involved. In C++, common forms include compile-time polymorphism (such as function/operator overloading and templates) and runtime polymorphism (commonly virtual functions used through base-class pointers or references).

In this project: Operator overloading and templates are compile-time language features that support reusable, type-specific behaviour. However, the program does not demonstrate runtime polymorphism using virtual functions.

// Operator overloading: the + operator is defined
// for CartItem objects in a meaningful way.
CartItem operator+(int extra) const {
    return CartItem(product, quantity + extra);
}

This is an example of an overloaded operator, but do not claim the project implements a virtual-function hierarchy. If asked about runtime polymorphism in the viva, define it and clearly state that it is not part of the current implementation.

Remember: Polymorphism allows a common interface to represent different behaviours; runtime polymorphism usually uses virtual functions in C++.

06

Constructors and access specifiers

INITIALISE OBJECTS SAFELY

Constructor definition: A constructor is a special member function that runs when an object is created. It initializes the object and can check that the initial values are valid.

Access specifiers: private members can be accessed by the class's own member functions and permitted friends; public members form the ordinary interface available to callers; protected members are also accessible to derived classes.

Product(int productId, string productName,
        double productPrice)
    : id(productId),
      name(std::move(productName)),
      price(productPrice) {
    if (price < 0)
        throw invalid_argument(
            "Product price cannot be negative.");
}

The colon introduces a member-initializer list, which initializes members before the constructor body executes. Here, the constructor prevents a product with a negative price from being created successfully.

Remember: Constructors initialize objects; access specifiers define who may access members.

REQUIRED IMPLEMENTATION / FIVE CONCEPTS

How the required concepts work in our C++ code

The following examples are based on the actual companion source file. These are the concepts to be able to point to and explain during your demonstration.

07

Composition

A HAS-A RELATIONSHIP

Definition: Composition is a relationship in which one object contains another object, using it as part of its structure. It is often called a “has-a” relationship. The contained object represents a component of the larger object.

In ForgeSupply: A CartItem has a Product and a quantity. A ShoppingCart has a collection of CartItem objects. This matches the domain: a line in the cart needs product details, and the cart consists of lines.

class CartItem {
private:
    Product product;
    int quantity;
};

class ShoppingCart {
private:
    vector<CartItem> items;
};

When the constructor of CartItem receives a product, it copies that product into its product member. The cart stores cart items in its own vector. In this implementation, the contained product is stored by value, not as a pointer to a shared product object.

Viva point: “A ShoppingCart has CartItems, and each CartItem has a Product.” This is composition, not inheritance.

08

Operator overloading

GIVE AN OPERATOR A CLASS-SPECIFIC MEANING

Definition: Operator overloading lets a programmer define how an existing C++ operator behaves when used with a user-defined type. It can make object operations more natural, but it does not change the operator's behaviour for built-in types such as ordinary integers.

In ForgeSupply: CartItem + 1 means “create a cart item with its quantity increased by one”. The overloaded << operator formats product and cart-item details for output streams.

CartItem operator+(int extra) const {
    return CartItem(product, quantity + extra);
}

// Usage:
item = item + 1;
cout << item;

The const after the member function means the function promises not to modify the original object's members. Instead, operator+ returns a new CartItem, which is assigned back to the existing item. The stream insertion overload returns the output stream by reference so expressions such as chained output can work.

Viva point: The project overloads + for quantity updates and << for readable output.

09

Function templates

WRITE GENERIC, REUSABLE CODE

Definition: A template is a C++ feature for writing code that can work with different types. A function template lets the compiler generate a suitable function for a type used by the program, provided that type supports the operations the function requires.

In ForgeSupply: findById searches a vector and checks each object's getId(). It can search the catalogue of Product objects without writing a separate search loop specifically for Product.

template <typename T>
int findById(const vector<T>& items, int id) {
    for (int i = 0; i < static_cast<int>(items.size()); ++i)
        if (items[i].getId() == id) return i;
    return -1;
}

T is a placeholder for a type. The ampersand in const vector<T>& passes the vector by reference instead of copying it, and const means this function does not modify the vector. The function returns the matching index or -1 if no matching ID exists.

Viva point: Templates reduce duplicate code. The type used must provide the getId() operation that the function calls.

10

Vectors

DYNAMIC COLLECTIONS FROM THE C++ STANDARD LIBRARY

Definition: std::vector is a sequence container that stores elements in order and can grow or shrink as elements are added or removed. Unlike a built-in fixed-size array, a vector manages its size dynamically.

In ForgeSupply: The catalogue uses vector<Product>, the shopping cart uses vector<CartItem>, and the demo order history uses vector<string>.

vector<Product> catalogue;
vector<CartItem> items;
vector<string> orderHistory;

items.emplace_back(product, quantity);
orderHistory.push_back("Demo order #1001");

emplace_back() constructs an element at the end of the vector using the supplied arguments. push_back() adds an existing value (or a value that can be constructed as an element). The program also uses indexing to access a product after the template returns its position.

Viva point: Vectors are used because the number of products or cart lines may change during execution.

11

Exception handling

HANDLE ERRORS WITHOUT SILENTLY ACCEPTING INVALID DATA

Definition: Exception handling is a mechanism for reporting and handling exceptional conditions. throw signals an error, try marks code that may produce an exception, and catch handles a matching exception.

In ForgeSupply: The code rejects negative prices, quantities below one, attempts to print a bill for an empty cart, and discount rates outside the range zero to one.

if (price < 0)
    throw invalid_argument(
        "Product price cannot be negative.");

try {
    cart.printBill(0.10);
} catch (const exception& error) {
    cerr << "Shopping cart error: "
         << error.what() << '\\n';
}

invalid_argument is used for invalid input values, while logic_error is used when billing is requested with an empty cart. The catch block in main() catches standard exceptions and prints their message. This makes invalid operations visible instead of silently continuing with an invalid result.

Viva point: throw raises the error; try surrounds risky operations; catch handles the error.

One complete example: from catalogue to bill

First, the catalogue vector stores Product objects. The findById template searches for a requested product. ShoppingCart::addProduct either creates a new CartItem or updates the quantity of an existing one. Composition links the cart and its items; operator+ updates quantity and operator<< prints details; vectors store the changing collections; exception handling rejects invalid inputs and billing requests. Finally, printBill calculates the subtotal, discount, estimated tax and total.

VIVA PREPARATION / CHECK YOUR UNDERSTANDING

Questions you should be able to answer

Use these prompts to practise explaining the design in your own words, rather than memorising a paragraph and hoping the examiner is feeling generous.

Why did we create separate Product, CartItem and ShoppingCart classes?

Each class represents a different responsibility. Product stores product details; CartItem connects a product to a chosen quantity and line total; ShoppingCart manages multiple cart items and billing. Separating responsibilities makes the design easier to understand and maintain.

What is the difference between encapsulation and abstraction?

Encapsulation groups state and behaviour and controls access to internal data. Abstraction exposes a simpler interface while hiding implementation details. Private members and public getters illustrate encapsulation; calling printBill() without manually doing each calculation illustrates abstraction.

What is the difference between composition and inheritance?

Composition is a “has-a” relationship, such as a cart having cart items. Inheritance is an “is-a” relationship, such as a hypothetical Machine class deriving from IndustrialProduct. The current project uses composition and does not implement an inheritance hierarchy.

Why is the quantity not changed directly from main()?

The quantity member is private. The program changes it through class operations that validate the requested change. This keeps the object's state under the class's control.

What does the const keyword mean in operator+()?

It indicates that the member function will not modify the current object through its members. The implementation returns a new cart item with the updated quantity, and the caller can assign that result back.

Why use a template for findById()?

It avoids writing nearly identical search functions for each supported object type. Any type passed to this function must provide the getId() method used by the search logic.

Why use vector instead of a fixed-size array?

The number of cart items can change at runtime. A vector can grow as new elements are added and provides convenient operations such as size(), indexing, push_back() and emplace_back().

What happens if the price is negative or the cart is empty?

The product constructor throws invalid_argument for a negative price. printBill() throws logic_error if the cart is empty. The surrounding try/catch in main() catches standard exceptions and displays an error message.

Does the website itself run the C++ code?

No. The visible website uses JavaScript for browser interactions. The C++17 program is a separate console demonstration. Connecting them would require a backend/API, which is not included in this version.

Does this project implement all four OOPS pillars?

It clearly demonstrates classes and objects, encapsulation, abstraction through public operations, and composition. It does not currently implement an inheritance hierarchy or runtime polymorphism with virtual functions. Operator overloading and templates are additional required C++ concepts demonstrated by the program.

✓

ORDER CONFIRMED

Good choice.

Your demo order has been recorded.