C++ PROGRAMMING ยท 40 MIN STUDY

Project: Inventory management with classes and STL

Design an inventory application with classes, encapsulation, maps, validation, and persistent storage.

Learning objectives

  • Model product state and operations in a class with private data.
  • Protect quantity and price invariants at the class boundary.
  • Choose between ordered map and hash-based unordered_map based on requirements.
  • Explain why binary floating-point is not a reliable general-purpose money representation.

Prerequisites: classes, constructors, exceptions, maps, and file I/O. This page is a guided project specification with focused code fragments; for a complete buildable multi-file example, follow the library catalogue capstone.

Project goal

Project scope: this page is a guided implementation brief with selected code fragments, not a complete source listing. A complete multi-file build-and-test example is available in the library catalogue capstone.

Create an inventory console application that tracks products by a unique SKU, name, quantity, and unit price. Users can add products, receive stock, sell stock, search, list, and save data.

Encapsulate product rules

#include <cstdint>
#include <limits>
#include <stdexcept>
#include <string>
#include <utility>

class Product {
public:
    Product(std::string sku, std::string name, int quantity,
            std::int64_t price_minor_units)
        : sku_(std::move(sku)), name_(std::move(name)),
          quantity_(quantity), price_minor_units_(price_minor_units) {
        if (sku_.empty() || name_.empty() || quantity_ < 0 ||
            price_minor_units_ < 0) {
            throw std::invalid_argument("invalid product data");
        }
    }

    const std::string& sku() const { return sku_; }
    int quantity() const { return quantity_; }
    std::int64_t price_minor_units() const { return price_minor_units_; }

    void receive(int amount) {
        if (amount <= 0) throw std::invalid_argument("amount");
        if (amount > std::numeric_limits<int>::max() - quantity_)
            throw std::overflow_error("quantity overflow");
        quantity_ += amount;
    }

    void sell(int amount) {
        if (amount <= 0 || amount > quantity_)
            throw std::invalid_argument("stock");
        quantity_ -= amount;
    }

private:
    std::string sku_, name_;
    int quantity_;
    std::int64_t price_minor_units_; // e.g. paise for a two-decimal currency
};

This version includes the headers it uses, validates constructor inputs, prevents negative stock, and checks for integer overflow before receiving more stock. It stores price in integer minor units (for example, paise in a currency with two decimal places); the currency and rounding policy must be documented by the application.

Choose a container

#include <map>
std::map<std::string, Product> inventory;
inventory.emplace("SKU-100", Product{"SKU-100", "Keyboard", 12, 79900}); // 799 rupees in paise
auto it = inventory.find("SKU-100");
if (it != inventory.end()) it->second.sell(2);

std::map keeps keys ordered and offers O(log n) lookup, insertion, and removal. An unordered_map offers average O(1) lookup but does not preserve key order. Select based on the application's requirements, not a slogan that one container is always faster.

Design operations

  1. Add product only when SKU is not already present.
  2. Receive stock with a positive quantity.
  3. Sell only when enough stock exists.
  4. Search by SKU and display all products.
  5. Calculate inventory value carefully; consider rounding and money representation.
  6. Persist and reload records, validating every field.

Money and data correctness

Binary floating-point cannot represent every decimal fraction exactly. For real financial systems, store money in the smallest currency unit as an integer or use a decimal type/library with a documented rounding policy. A teaching inventory app may use double for demonstration, but should not imply it is ideal for accounting.

Test plan

  • Attempt to sell more units than available.
  • Receive zero or negative stock.
  • Duplicate SKU and missing SKU.
  • Empty inventory and malformed saved file.
  • Large quantities and price values.

Extensions

Add low-stock alerts, category filters, sorting, transaction history, and a report. Keep business rules in classes or service functions rather than duplicating them in menu code.

References