在现代C++编程中,内存管理一直是开发者关注的重点。传统的裸指针虽然灵活,但容易导致内存泄漏和悬挂指针等问题。为了解决这些问题,C++11引入了智能指针,提供了更安全、自动化的内存管理方式。本文将深入探讨如何利用智能指针设计一个高效的库存管理系统,展示其强大的自学能力和技术实力。
智能指针概述
智能指针是C++标准库中用于自动管理动态分配内存的工具。主要包括:
std::unique_ptr
:独占所有权,确保同一时刻只有一个指针拥有对象的所有权。std::shared_ptr
:共享所有权,允许多个指针共同拥有同一对象,引用计数为零时自动释放对象。std::weak_ptr
:弱引用,不增加引用计数,用于打破循环引用。
设计思路
我们将构建一个库存管理系统,包含以下组件:
- 商品基类(
Item
):定义商品的基本属性和接口。 - 具体商品类(
Book
和Electronic
):继承自Item
,实现具体商品的描述。 - 库存类模板(
Inventory
):使用智能指针管理商品对象,实现库存的增删查改功能。 - 仓库类(
Warehouse
):管理商品的存放位置,确保库存与仓库的协同工作。#include <iostream> #include <map> #include <memory> #include <string> #include <vector> class Item { protected: std::string id; public: Item(const std::string &i) : id(i) {} virtual ~Item() = default; virtual std::string getDescription() const = 0; std::string getID() const { return id; } }; class Book : public Item { std::string name; std::string author; public: Book(const std::string &i, const std::string &n, const std::string &a) : Item(i), name(n), author(a) {} std::string getDescription() const override { return "Book ID: " + id + " Book name " + name + " by " + author; } std::string getName() const { return name; } }; class Electronic : public Item { double voltage; public: Electronic(const std::string &i, double v) : Item(i), voltage(v) {} std::string getDescription() const override { return "Electronic ID: " + id + " (" + std::to_string(voltage) + "V)"; } }; template <typename T> class Inventory { std::map<std::string, T> items; std::map<std::string, int> quantities; public: void addItem(T item, int quantity) { items[item->getID()] = item; quantities[item->getID()] = quantity; } void updateQuantity(const std::string &id, int delta) { if (quantities.find(id) != quantities.end()) { quantities[id] += delta; } } void listInventory() const { for (const auto &[id, item] : items) { std::cout << item->getDescription() << " - Quantity: " << quantities.at(id) << "\n"; } } void searchIdByName(const std::string &nm) const { bool found = false; for (const auto &[id, item] : items) { if (item->getDescription().find(nm) != std::string::npos) { std::cout << "The ID is " << id << std::endl; found = true; } } if (!found) { std::cout << "None." << std::endl; } } }; int now = 1; class Warehouse { protected: std::map<int, std::string> warehouse; public: void insideItem(std::string id) { if (now <= 50) { warehouse[now] = id; now++; } else { std::cout << "Warehouse is full!" << std::endl; } } void takeItem(std::string id) { bool found = false; for (const auto &[place, itemId] : warehouse) { if (itemId == id) { std::cout << "I find " << id << " at position " << place << std::endl; found = true; break; } } if (!found) { std::cout << id << " not found in the warehouse." << std::endl; } } }; void demoOperations() { Inventory<std::shared_ptr<Item>> inventory; Warehouse warehouse; auto book = std::make_shared<Book>("B002", "我看见的世界", "李飞飞"); inventory.addItem(book, 20); warehouse.insideItem(book->getID()); auto lamp = std::make_shared<Electronic>("E002", 220.0); inventory.addItem(lamp, 50); warehouse.insideItem(lamp->getID()); auto book2 = std::make_shared<Book>("B003", "Cien anos de soledad", "Marcus"); inventory.addItem(book2, 15); warehouse.insideItem(book2->getID()); inventory.updateQuantity("B002", 5); inventory.updateQuantity("E002", -1); std::cout << "\n--- 库存列表 ---\n"; inventory.listInventory(); warehouse.takeItem("B003"); inventory.searchIdByName("Cien anos de soledad"); } int main() { demoOperations(); return 0; }