C++对函数和向量感到困惑

C++ Confused about functions and vectors

本文关键字:向量 函数 C++      更新时间:2023-10-16

希望这将是我一段时间内的最后一个问题。

我有点困惑为什么我的功能不起作用。这是我的代码(稍后我会详细解释):

#include <iostream>
#include <string>
#include <vector>
#include <sstream>
using namespace std;

class Inventory {
public:
    void SetSumInv(int prcInDllrs, int individualquantity) {
        priceInDollars = priceInDollars + (prcInDllrs * individualquantity);
        totalInvPriceInDollars = totalInvPriceInDollars + priceInDollars;
    }
    void SetItemPrice(int whatever) {
        itemsPrice = whatever;
    }
    void SetName(string nm)
    {
        name = nm;
    };
    void SetQuantity(int qnty)
    {
        quantity = qnty;
    };
    void SetAuthor(string athr) {
        author = athr;
    }
    void SetExpiration(string expir)
    {
        expiration = expir;
    };
    virtual void Print(){
        cout << name << " x" << quantity << " for: $" << itemsPrice; //" (Expires: " << expiration << ")";
        if (expiration.size() != 0) {
            cout << " (Expires: " << expiration << ")" << endl;
        }
        else {
            cout << " (Author: " << author << ")" << endl;
        }
    }
    void PrintInventory(vector<Inventory*> inventory) {
        unsigned int i = 0;
        if (inventory.size() == 0) {
            cout << "No items to print." << endl;
        }
        else {
            for (i = 0; i<inventory.size(); ++i) {
                cout << i << " - ";
                inventory.at(i)->Print();
            }
            cout << "Total inventory value: " << priceInDollars;
        }
        return;
    }
    void AddItemToInventory()
    {
    }
    vector<Inventory*> AddProduceToInventory(vector<Inventory*> inventory)
    {
        Inventory* prdc;
        string usrInptName = "";
        string usrInptQntyStr = "";
        istringstream inSS;
        istringstream inDD;
        int usrInptQnty = 0;
        string usrInptExpr = "";
        string usrInptPrcStr = "";
        int usrInptPrc = 0;
        int ItemCost = 0;
        cout << "Enter name of new produce: ";
        getline(cin, usrInptName);
        SetName(usrInptName);
        cout << "Enter quantity: ";
        getline(cin, usrInptQntyStr);
        inSS.str(usrInptQntyStr);
        inSS >> usrInptQnty;
        inSS.clear();
        SetQuantity(usrInptQnty);
        cout << "Enter expiration date: ";
        getline(cin, usrInptExpr);
        SetExpiration(usrInptExpr);
        cout << "Enter the price per item: $";
        getline(cin, usrInptPrcStr);
        inDD.str(usrInptPrcStr);
        inDD >> usrInptPrc;
        inDD.clear();
        SetItemPrice(usrInptPrc);
        ItemCost = (usrInptPrc * usrInptQnty);
        prdc = new Inventory;
        prdc->SetName(usrInptName);
        prdc->SetQuantity(usrInptQnty);
        prdc->SetExpiration(usrInptExpr);
        prdc->SetSumInv(usrInptPrc, usrInptQnty);
        prdc->SetItemPrice(usrInptPrc);
        inventory.push_back(prdc);
        return inventory;
    }
    void AddBookToInventory()
    {
    }
    vector<Inventory*> AddBookToInventory(vector<Inventory*> inventory) {
        Inventory* prdct;
        string usrInptName = "";
        string usrInptQntyStr = "";
        istringstream inSS;
        int usrInptQnty = 0;
        string usrInptAthr = "";
        string usrInptPrcStr = "";
        int usrInptPrc = 0;
        istringstream inDD;
        int sum = 0;
        int ItemCost = 0;
        cout << "Enter name of new book: ";
        getline(cin, usrInptName);
        cout << "Enter quantity: ";
        getline(cin, usrInptQntyStr);
        inSS.str(usrInptQntyStr);
        inSS >> usrInptQnty;
        inSS.clear();
        cout << "Enter author: ";
        getline(cin, usrInptAthr);
        cout << "Enter the price per item: $";
        getline(cin, usrInptPrcStr);
        inDD.str(usrInptPrcStr);
        inDD >> usrInptPrc;
        inDD.clear();
        ItemCost = (usrInptPrc * usrInptQnty);
        prdct = new Inventory;
        prdct->SetName(usrInptName);
        prdct->SetQuantity(usrInptQnty);
        prdct->SetSumInv(usrInptPrc, usrInptQnty);
        prdct->SetAuthor(usrInptAthr);
        prdct->SetItemPrice(usrInptPrc);
        inventory.push_back(prdct);

        return inventory;
    }
    void UpdateItemQtyInventory()
    {}
    //This is the update function in which we can change how many items a certain purchase has
    vector<Inventory*> UpdateItemQtyInInventory(vector<Inventory*> inventory) {
        string usrIndexChoiceStr = "";
        unsigned int usrIndexChoice = 0;
        istringstream inSS;
        string usrInptQntyStr = "";
        int usrInptQnty = 0;

        if (inventory.size() == 0) {
            cout << "No items to update." << endl;
        }
        else {
            PrintInventory(inventory);
            do {
                cout << "Update which item #: ";
                getline(cin, usrIndexChoiceStr);
                inSS.str(usrIndexChoiceStr);
                inSS >> usrIndexChoice;
                inSS.clear();
            } while (!(usrIndexChoice < inventory.size()));
            cout << "Enter new quantity: ";
            getline(cin, usrInptQntyStr);
            inSS.str(usrInptQntyStr);
            inSS >> usrInptQnty;
            inSS.clear();
            inventory.at(usrIndexChoice)->SetQuantity(usrInptQnty);
        }
        return inventory;
    }
    void RemoveItemFromInventory()
    {}
    //Here we will be removing an entire item from the inventory
    vector<Inventory*> RemoveItemFromInventory(vector<Inventory*> inventory) {
        istringstream inSS;
        string usrIndexChoiceStr = "";
        unsigned int usrIndexChoice = 0;
        string usrInptQntyStr = "";
        if (inventory.size() == 0) {
            cout << "No items to remove." << endl;
        }
        else {
            PrintInventory(inventory);
            do {
                cout << "Remove which item #: ";
                getline(cin, usrIndexChoiceStr);
                inSS.str(usrIndexChoiceStr);
                inSS >> usrIndexChoice;
                inSS.clear();
            } while (!(usrIndexChoice < inventory.size()));
            inventory.erase(inventory.begin() + usrIndexChoice);
        }
        return inventory;
    }
    void GetTotalValueAsPrice()
    {
    }
protected:
    string name;
    int    quantity = 0;
    int priceInDollars = 0;
    int totalCost = 0;
    int itemsPrice = 0;
    string expiration;
    string author;
private:
    int totalInvPriceInDollars = 0;
};
int main() {
    vector<Inventory*> INVENTORY;
    string usrInptOptn = "default";
    string usrInptOptn2 = "default";
    Inventory update;
    while (true) {
        // Get user choice
        cout << "nEnter (p)rint, (a)dd, (u)pdate, (r)emove, or (q)uit: ";
        getline(cin, usrInptOptn);
        // Process user choice
        if (usrInptOptn.size() == 0) {
            continue;
        }
        else if (usrInptOptn.at(0) == 'p') {
            update.PrintInventory(INVENTORY);               //Different! 
        }
        else if (usrInptOptn.at(0) == 'a') {///I don't know what the difference is between the three slashes and the two, but they are different!
            cout << "nEnter (b)ook or (p)roduce: ";
            getline(cin, usrInptOptn2);
            if (usrInptOptn2.at(0) == 'b') {
                INVENTORY = update.AddBookToInventory(INVENTORY);                                   //Supposed to look like: INV = AddItem...(INV);
            }
        else if (usrInptOptn2.at(0) == 'p') {
                INVENTORY = update.AddProduceToInventory(INVENTORY);
            }
            else
            {
                continue;
            }
        }
        else if (usrInptOptn.at(0) == 'u') {
            INVENTORY = update.UpdateItemQtyInInventory(INVENTORY);
            }
        else if (usrInptOptn.at(0) == 'r') {
            INVENTORY = update.RemoveItemFromInventory(INVENTORY);
            }
        else if (usrInptOptn.at(0) == 'q') {
            cout << "nGood bye." << endl;
            break;
        }
    }
    return 0;
}

所以现在。在我的类Inventory,public:void SetSumInv中,这个程序所做的是获取用户输入,并统计所有内容,所以当它打印时,它应该打印库存,然后打印库存价值的总和(以美元为单位)。我试过运行这个,但它不会打印库存价值的总和。这里怎么了?我想不通。

谢谢!

解析代码后;我花了相当长的时间才把它清理干净。我没有时间搜索你的bug,但我能做的是稍微清理一下你的课,这样读起来更友好。我对您类的一些函数调用进行了一些修改,这些修改将在注释中进行解释。我还删除了您在类中声明的所有空函数。我还更改了类命名约定的外观(这只是用户偏好)

库存.h

#ifndef INVENTORY_H
#define INVENTORY_H
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
class Inventory {    
protected:
    std::string m_strName;
    std::string m_strExpiration;
    std::string m_strAuthor;
    int m_quantity;
    int m_priceInDollars;
    int m_totalCost;
    int m_itemsPrice;    
private:
    int m_totalInvPriceInDollars;
public:
    Inventory(); // Default Constructor
    void setName( const std::string& nm );
    void setAuthor( const std::string& athr );
    void setExpiration( const std::string& expir );
    void setSumInv( int prcInDllrs, int individualquantity ); 
    void setItemPrice( int whatever );   
    void setQuantity( int qnty );    
    virtual void print(); 
    void printInventory( std::vector<Inventory*>& inventory ); 
    // I changed these methods to pass by reference opposed to returning from function call
    void addProduceToInventory( std::vector<Inventory*>& inventory );   
    void addBookToInventory( std::vector<Inventory*>& inventory ); 
    void updateItemQtyInInventory( std::vector<Inventory*>& inventory ); 
    void removeItemFromInventory( std::vector<Inventory*>& inventory ); 
}; // Invenotory
#endif // INVENTORY_H

库存.cpp

#include "Inventory.h"
// ----------------------------------------------------------------------------
// Inventory()
Inventory::Inventory() :
m_quantity( 0 ),
m_itemsPrice( 0 ),
m_priceInDollars( 0 ),
m_totalCost( 0 ),
m_totalInvPriceInDollars( 0 ) {
} // Inventory
// ----------------------------------------------------------------------------
// setSumInv()
void Inventory::setSumInv( int prcInDllrs, int individualquantity ) {
    m_priceInDollars = m_priceInDollars + (prcInDllrs * individualquantity);
    m_totalInvPriceInDollars = m_totalInvPriceInDollars + m_priceInDollars;
} // setSumInv
// ----------------------------------------------------------------------------
// setItemPrice()
void Inventory::setItemPrice( int whatever ) {
    m_itemsPrice = whatever;
} // setItemPrice
// ----------------------------------------------------------------------------
// setQuantity()
void Inventory::setQuantity( int qnty ) {
    m_quantity = qnty;
} // setQuantity
// ----------------------------------------------------------------------------
// setName()
void Inventory::setName( const std::string& strName ) {
    m_strName = strName;
} // setName
// ----------------------------------------------------------------------------
// setAuthor()
void Inventory::setAuthor( const std::string& strAuthor ) {
    m_strAuthor = strAuthor;
} // setAuthor
// ----------------------------------------------------------------------------
// setExpiration()
void Inventory::setExpiration( const std::string& strExpir ) {
    m_strExpiration = strExpir;
} // setExpiration
// ----------------------------------------------------------------------------
// print()
void Inventory::print() {
    std::cout << m_strName << " x" << m_quantity << " for: $" << m_itemsPrice; //" (Expires: " << expiration << ")";
    if ( m_strExpiration.size() != 0 ) {
        std::cout << " (Expires: " << m_strExpiration << ")" << std::endl;
    } else {
        std::cout << " (Author: " << m_strAuthor << ")" << std::endl;
    }
} // print
// ----------------------------------------------------------------------------
// printInventory()
void Inventory::printInventory( std::vector<Inventory*>& vInventory ) {
    unsigned int i = 0;
    if ( vInventory.size() == 0) {
        std::cout << "No items to print." << std::endl;
    } else {
        for ( i = 0; i < vInventory.size(); ++i ) {
            std::cout << i << " - ";
            vInventory.at(i)->print();
        }
        std::cout << "Total inventory value: " << m_priceInDollars;
    }
} // printInventory
// ----------------------------------------------------------------------------
// addProduceToInventory()
void Inventory::addProduceToInventory( std::vector<Inventory*>& vInventory ) {
    std::string usrInptName = "";
    std::string usrInptQntyStr = "";
    std::istringstream inSS;
    std::istringstream inDD;
    int usrInptQnty = 0;
    std::string usrInptExpr = "";
    std::string usrInptPrcStr = "";
    int usrInptPrc = 0;
    int itemCost = 0;
    std::cout << "Enter name of new produce: ";
    getline( std::cin, usrInptName );
    setName( usrInptName );
    std::cout << "Enter quantity: ";
    std::getline( std::cin, usrInptQntyStr );
    inSS.str( usrInptQntyStr );
    inSS >> usrInptQnty;
    inSS.clear();
    setQuantity( usrInptQnty );
    std::cout << "Enter expiration date: ";
    getline( std::cin, usrInptExpr );
    setExpiration( usrInptExpr );
    std::cout << "Enter the price per item: $";
    getline( std::cin, usrInptPrcStr );
    inDD.str( usrInptPrcStr );
    inDD >> usrInptPrc;
    inDD.clear();
    setItemPrice( usrInptPrc );
    itemCost = usrInptPrc * usrInptQnty;
    Inventory* pInv = nullptr;   // Initialize Pointers to nullptr 
    pInv = new Inventory;        // Using New Memory (Dyanamic) - Where Is This Being Deleted?
    pInv->setName( usrInptName );
    pInv->setQuantity( usrInptQnty );
    pInv->setExpiration( usrInptExpr );
    pInv->setSumInv( usrInptPrc, usrInptQnty );
    pInv->setItemPrice(usrInptPrc);
    vInventory.push_back( pInv );
} // addProduceToInventory 
// ----------------------------------------------------------------------------
// addBookToInventory()
void Inventory::addBookToInventory( std::vector<Inventory*>& inventory) {   
    std::string usrInptName = "";
    std::string usrInptQntyStr = "";
    std::istringstream inSS;
    int usrInptQnty = 0;
    std::string usrInptAthr = "";
    std::string usrInptPrcStr = "";
    int usrInptPrc = 0;
    std::istringstream inDD;
    int sum = 0;
    int itemCost = 0;
    std::cout << "Enter name of new book: ";
    getline( std::cin, usrInptName );
    std::cout << "Enter quantity: ";
    getline( std::cin, usrInptQntyStr );
    inSS.str( usrInptQntyStr );
    inSS >> usrInptQnty;
    inSS.clear();
    std::cout << "Enter author: ";
    getline( std::cin, usrInptAthr );
    std::cout << "Enter the price per item: $";
    getline( std::cin, usrInptPrcStr );
    inDD.str( usrInptPrcStr );
    inDD >> usrInptPrc;
    inDD.clear();
    itemCost = usrInptPrc * usrInptQnty;
    Inventory* pInv = nullptr;   // Initialize pointers to nullptr;
    pInv = new Inventory;        // Using New Memory (Dyanamic) - Where Is This Being Deleted?
    pInv->setName( usrInptName );
    pInv->setQuantity( usrInptQnty );
    pInv->setSumInv( usrInptPrc, usrInptQnty );
    pInv->setAuthor( usrInptAthr );
    pInv->setItemPrice( usrInptPrc );
    inventory.push_back( pInv );
} // addBookToInventory
// ----------------------------------------------------------------------------
// updateItemQtyInInventory()
// This is the update function in which we can change how many items a certain purchase has
void Inventory::updateItemQtyInInventory( std::vector<Inventory*>& vInventory ) {
    std::string usrIndexChoiceStr = "";        
    unsigned int usrIndexChoice = 0;
    std::istringstream inSS;
    std::string usrInptQntyStr = "";
    int usrInptQnty = 0;
    if ( vInventory.size() == 0 ) {
        std::cout << "No items to update." << std::endl;
    } else {
        printInventory( vInventory );
        do {
            std::cout << "Update which item #: ";
            getline( std::cin, usrIndexChoiceStr );
            inSS.str( usrIndexChoiceStr );
            inSS >> usrIndexChoice;
            inSS.clear();
        } while ( !(usrIndexChoice < vInventory.size()) );
        std::cout << "Enter new quantity: ";
        getline( std::cin, usrInptQntyStr );
        inSS.str( usrInptQntyStr );
        inSS >> usrInptQnty;
        inSS.clear();
        vInventory.at(usrIndexChoice)->setQuantity(usrInptQnty);
    }
} // updateItemQtyInInventory
// ----------------------------------------------------------------------------
// removeItemFromInventory()
// Here we will be removing an entire item from the inventory
void Inventory::removeItemFromInventory( std::vector<Inventory*>& vInventory) {
    std::istringstream inSS;
    std::string usrIndexChoiceStr = "";
    unsigned int usrIndexChoice = 0;
    std::string usrInptQntyStr = "";
    if ( vInventory.size() == 0 ) {
        std::cout << "No items to remove." << std::endl;
    } else {
        printInventory( vInventory );
        do {
            std::cout << "Remove which item #: ";
            getline( std::cin, usrIndexChoiceStr );
            inSS.str( usrIndexChoiceStr );
            inSS >> usrIndexChoice;
            inSS.clear();
        } while ( !(usrIndexChoice < vInventory.size()) );
        vInventory.erase( vInventory.begin() + usrIndexChoice );
    }
} // removeItemFromInventory

main.cpp

#include <iostream>
#include <string>
#include <vector>
#include <sstream>
//using namespace std; // Bad Practice To Use This In A Global Scope! 
#include "Inventory.h"
// ----------------------------------------------------------------------------
// main()
int main() {
    std::vector<Inventory*> vInventory;
    std::string strUsrInptOptn = "default";
    std::string strUsrInptOptn2 = "default";
    Inventory update;
    while (true) {
        // Get user choice
        std::cout << "nEnter (p)rint, (a)dd, (u)pdate, (r)emove, or (q)uit: ";
        getline( std::cin, strUsrInptOptn);
        // Process user choice
        if ( strUsrInptOptn.size() == 0 ) {
            continue;
        } else if ( strUsrInptOptn.at(0) == 'p' ) {
            update.printInventory( vInventory );      //Different!
        } else if ( strUsrInptOptn.at(0) == 'a' ) { ///I don't know what the difference is between the three slashes and the two, but they are different!
            std::cout << "nEnter (b)ook or (p)roduce: ";
            getline( std::cin, strUsrInptOptn2 );
            if ( strUsrInptOptn2.at(0) == 'b' ) {
                update.addBookToInventory( vInventory );    //Supposed to look like: INV = AddItem...(INV);
            } else if ( strUsrInptOptn2.at(0) == 'p' ) {
                update.addProduceToInventory( vInventory );
            } else {
                continue;
            }
        } else if ( strUsrInptOptn.at(0) == 'u' ) {
            update.updateItemQtyInInventory( vInventory );
        } else if ( strUsrInptOptn.at(0) == 'r' ) {
            update.removeItemFromInventory( vInventory );
        } else if ( strUsrInptOptn.at(0) == 'q') {
            std::cout << "nGood bye." << std::endl;
            break;
        }
    } // while
    return 0;
} // main

有了这个,代码看起来更干净,感觉更优雅。main.cpp没有杂乱的代码行;保持CCD_ 2简短始终是一种很好的做法,因为这是主可执行文件的起点。我为您的库存创建了一个类,并将其放在*.h*.cpp文件中自己的模块中。我还将其声明与定义或执行分开。这样,如果其他人正在查看您的源代码以使用它;他们不必确切地知道函数是如何工作的,只需要知道它应该做什么。接口或*.h文件应该告诉你关于类对象以及如何使用它所需要知道的一切。此外,这允许更干净、更快的构建时间,因为只有当您在内部更改了某些内容而不是重建整个解决方案时,才需要编译此类的*.cpp文件。

现在,在某些情况下,您可能希望在头文件中包含实现,而在某些情况中,您别无选择,必须将其包含在内。如果您的方法被声明为inline,或者您正在创建一个仅头库,则可能希望实现在头文件内。如果您正在创建class templatesfunction templates,但当您有这两种类型inline member functionsclass template member functionsfunction templates时,这些类型通常会在内联文件或*.inl中找到,并且您会使用#include指令将该文件包含在类声明之外的#endif头保护之前;如果您使用#pragma once而不是#ifndef #define #endif,那么您只需要在类声明之后使用它。

一旦你开始有一个你喜欢的恒定的代码结构;调试和查找错误将变得更加容易。

在你的问题之外,我想我注意到了你介绍的另一个错误,你可能知道,也可能不知道;我想你的程序中可能有内存泄漏!

我希望这能对你有所帮助。如果我在接下来的几天内有机会;我可能会继续尝试调试您的代码,或者尝试以稍微优雅的方式重写您的程序。如果我真的有时间,我会把它作为另一个答案发布。

我已经编写了用户请求的程序版本。我花了一点时间来解决错误,并确保它按预期工作。这并不意味着它完全没有bug。如果有人碰巧发现任何错误,请随时发表评论并列出任何错误,以便我可以修复它们并进行适当的编辑。

该程序是用C++编写的,使用的是使用VS 2015编译和构建的Win32控制台应用程序。

我在这里所做的是创建一个小的类层次结构。StoreItem类是一个抽象基类,这意味着您不能直接创建此类型的对象,因为它的构造函数受到保护。从这个基类继承的任何类对象都可以公开构造。我这样做是因为不同的产品类型可能有不同的信息。

我获取了所有产品类型的常见信息,并使用受保护的成员和公共访问函数将这些信息存储到基类中。基类中唯一的私有成员是Type,继承的类正在构造中。这些只是包含数据和方法的对象。main.cpp0类完成了存储和删除项目、计算总数和打印列表的大部分工作。

我这样设计它,使StoreItem及其继承的类与iostream对象没有任何依赖关系。Inventory类仅在其打印方法中使用std::cout对象。

与输入或std::cin对象一起工作的代码的唯一部分位于workingwhile循环中的main函数内。

拥有这样的结构,可以使这些类成为模块化的或可重用的。这也使得添加其他类型或存储项目变得容易。您必须创建另一个从StoreItem派生的类,在Enumerated类型中添加,然后在Inventory和用户选择分支中重复添加适当函数的过程。

这可以简化一点,但我试图让它尽可能接近用户的原始程序。我没有选择使用通用模板类型,这也是一种非常有用和有效的实现方式,可以减少代码冗余。人们需要掌握这些基本概念,然后才能开始进入更高级的主题。

stdafx.h

#ifndef STDAFX_H
#define STDAFX_H
#include <stdio.h>
#include <tchar.h>
#include <conio.h>
#include <string>
#include <iostream>
#include <memory>
//#include <sstream> // Not Using stringstring, istringstream, or ostringstream
#include <vector>
#endif // STDAFX_H

stdafx.cpp

#include "stdafx.h"

StoreItem.h

#ifndef STORE_ITEM_H
#define STORE_ITEM_H
class StoreItem {
public:
    enum ItemType {
        ITEM_BOOK = 0,
        ITEM_PRODUCE,
    }; // ItemType
protected:
    std::string     m_strItemName;
    float           m_priceInDollars;
private:
    ItemType m_type;
public:
    std::string getItemName() const;
    float       getItemPrice() const;
    void setItemName( const std::string& strItemName );
    void setItemPrice( float price );
    ItemType getItemType() const;
protected:
    explicit StoreItem( ItemType type );
    StoreItem( ItemType type, const std::string& strItemName, float priceInDollars );
}; // StoreItem
#endif // STORE_ITEM_H

StoreItem.cpp

#include "stdafx.h"
#include "StoreItem.h"
// ----------------------------------------------------------------------------
// StoreItem()
StoreItem::StoreItem( ItemType type ) :
m_type( type ) {
} // StoreItem
// ----------------------------------------------------------------------------
// StoreItem()
StoreItem::StoreItem( ItemType type, const std::string& strItemName, float priceInDollars ) :
m_type( type ),
m_strItemName( strItemName ),
m_priceInDollars( priceInDollars ){
} // StoreItem
// ----------------------------------------------------------------------------
// getItemType()
StoreItem::ItemType StoreItem::getItemType() const {
    return m_type;
} // getItemType
// ----------------------------------------------------------------------------
// setItemName()
void StoreItem::setItemName( const std::string& strItemName ) {
    m_strItemName = strItemName;
} // setItemName
// ----------------------------------------------------------------------------
// getItemName()
std::string StoreItem::getItemName() const {
    return m_strItemName;
} // getItemName
// ----------------------------------------------------------------------------
// setItemPrice()
void StoreItem::setItemPrice( float priceInDollars ) {
    m_priceInDollars = priceInDollars;
} // setItemPrice
// ----------------------------------------------------------------------------
// getItemPrice()
float StoreItem::getItemPrice() const {
    return m_priceInDollars;
} // getItemPrice

Book.h

#ifndef BOOK_H
#define BOOK_H
#include "StoreItem.h"
class Book sealed : public StoreItem {
private:
    std::string m_strAuthorName;
public:
    Book();
    Book( const std::string& strItemName, float priceInDollars, const std::string& strAuthor );
    void setAuthorName( const std::string& strAuthor );
    std::string getAuthorName() const;
}; // Book
#endif // BOOK_H

Book.cpp

#include "stdafx.h"
#include "Book.h"
// ----------------------------------------------------------------------------
// Book()
Book::Book() :
StoreItem( ITEM_BOOK ) {
} // Book
// ----------------------------------------------------------------------------
// Book()
Book::Book( const std::string& strItemName, float priceInDollars, const std::string& strAuthorName ) :
StoreItem( ITEM_BOOK, strItemName, priceInDollars ),
m_strAuthorName( strAuthorName ) {
} // Book
// ----------------------------------------------------------------------------
// setAuthorName()
void Book::setAuthorName( const std::string& strAuthorName ) {
    m_strAuthorName = strAuthorName;
} // setAuthorName
// ----------------------------------------------------------------------------
// getAuthorName()
std::string Book::getAuthorName() const {
    return m_strAuthorName;
} // getAuthorName

生产.h

#ifndef PRODUCE_H
#define PRODUCE_H
#include "StoreItem.h"
class Produce sealed : public StoreItem {
private:
    std::string m_strExpirationDate;
public:
    Produce();
    Produce( const std::string& strItemName, float priceInDollars, const std::string& strExpirationDate );
    void setExpirationDate( const std::string& strExpirationDate );
    std::string getExpirationDate() const;
}; // Produce
#endif // PRODUCE_H

生成.cpp

#include "stdafx.h"
#include "Produce.h"
// ----------------------------------------------------------------------------
// Produce()
Produce::Produce() :
StoreItem( ITEM_PRODUCE ) {
} // Produce
// ----------------------------------------------------------------------------
// Produce()
Produce::Produce( const std::string& strItemName, float priceInDollars, const std::string& strExpirationDate ) :
StoreItem( ITEM_PRODUCE, strItemName, priceInDollars ),
m_strExpirationDate( strExpirationDate ) {
} // Produce
// ----------------------------------------------------------------------------
// setExpirationDate()
void Produce::setExpirationDate( const std::string& strExpirationDate ) {
    m_strExpirationDate = strExpirationDate;
} // setExpirationDate
// ----------------------------------------------------------------------------
// getExpirationDate()
std::string Produce::getExpirationDate() const {
    return m_strExpirationDate;
} // getExpirationDate

库存.h

#ifndef INVENTORY_H
#define INVENTORY_H
#include "StoreItem.h" // Needed For StoreItem::ItemType
class Book;
class Produce;
class Inventory {
private:
    typedef std::vector<std::shared_ptr<Book>>      PtrBooks;
    typedef std::vector<std::shared_ptr<Produce>>   PtrProduce;
    PtrBooks    m_vBooks;
    PtrProduce  m_vProduce;
public:
    void addBook( const std::string& strName, const std::string& strAuthor, float price );
    void addProduce( const std::string& strName, const std::string& strExpiration, float price );
    void removeItemFromIventory( StoreItem::ItemType type, const std::string& strItemName, unsigned idx );
    void showInventory() const;
    bool isBookListEmpty() const;
    bool isProduceListEmpty() const;
}; // Inventory

库存.cpp

#include "stdafx.h"
#include "Inventory.h"
#include "Book.h"
#include "Produce.h"
// ----------------------------------------------------------------------------
// addBook()
void Inventory::addBook( const std::string& strName, const std::string& strAuthor, float price ) {
    m_vBooks.push_back( std::shared_ptr<Book>( new Book( strName, price, strAuthor ) ) );
} // addItemTo
// addProduce()
void Inventory::addProduce( const std::string& strName, const std::string& strExpiration, float price ) {
    m_vProduce.push_back( std::shared_ptr<Produce>( new Produce( strName, price, strExpiration ) ) );
} // addProduce
// ----------------------------------------------------------------------------
// removeItemFromInventory()
void Inventory::removeItemFromIventory( StoreItem::ItemType type, const std::string& strItemName, unsigned idx ) {
    if ( strItemName.empty() ) {
        // throw Exeption Here
        return;
    }
    unsigned counter = 1; // User Based, Not Vector or Array Based
    if ( type == StoreItem::ITEM_BOOK ) {
        PtrBooks::iterator it = m_vBooks.begin();
        for ( ; it != m_vBooks.end(); ++it ) {
            if ( it->get()->getItemName() == strItemName && counter == idx ) {
                // Found It
                it->reset();
                m_vBooks.erase( it );
                return;
            }
            counter++;
        }
    }
    // Reset Counter
    counter = 1;
    if ( type == StoreItem::ITEM_PRODUCE ) {
        PtrProduce::iterator it = m_vProduce.begin();
        for ( ; it != m_vProduce.end(); ++it ) {
            if ( it->get()->getItemName() == strItemName && counter == idx ) {
                // Found It
                it->reset();
                m_vProduce.erase( it );
                return;
            }
            counter++;
        }
    }
} // removeItemFromInventory()
// ----------------------------------------------------------------------------
// showInventory()
void Inventory::showInventory() const {
    float totalCostBooks = 0;
    float totalCostProduce = 0;
    std::flush( std::cout );
    std::cout << "n-------------" << std::endl
              << "Sales Invoice" << std::endl 
              << "-------------" << std::endl << std::endl;
    std::cout << "Book Information: " << std::endl;
    for ( unsigned u = 0; u < m_vBooks.size(); ++u ) {
        std::cout << u + 1 << ": " 
                  << m_vBooks.at( u ).get()->getItemName() << " " 
                  << m_vBooks.at( u ).get()->getAuthorName() << " "  
                  << "$" << m_vBooks.at( u ).get()->getItemPrice() << std::endl;
        totalCostBooks += m_vBooks.at( u ).get()->getItemPrice();
    }
    std::cout << "Total Cost Of Books: $" << totalCostBooks << std::endl << std::endl;
    std::cout << "Produce Information: " << std::endl;
    for ( unsigned u = 0; u < m_vProduce.size(); ++u ) {
        std::cout << u + 1 << ": "
                  << m_vProduce.at( u ).get()->getItemName() << " "
                  << m_vProduce.at( u ).get()->getExpirationDate() << " "
                  << "$" << m_vProduce.at( u ).get()->getItemPrice() << std::endl;
        totalCostProduce += m_vProduce.at( u ).get()->getItemPrice();
    }
    std::cout << "Total Cost Of Produce: $" << totalCostProduce << std::endl << std::endl;
    std::cout << "------------------" << std::endl
              << "Grand Total: $" << totalCostBooks + totalCostProduce << std::endl;
} // showInventory
// ----------------------------------------------------------------------------
// isBookListEmpty()
bool Inventory::isBookListEmpty() const {
    return m_vBooks.empty();
} // isBookListEmpty
// ----------------------------------------------------------------------------
// isProduceListEmpty()
bool Inventory::isProduceListEmpty() const {
    return m_vProduce.empty();
} // isProduceListEmpty

main.cpp

// StoreInventory.cpp : Defines the entry point for the console application.
#include "stdafx.h"
#include "Inventory.h"
int main() {
    Inventory inventory;
    std::string userInput;
    bool quit = false;
    while ( !quit ) {       
        std::cout << "nEnter (a)dd, (r)emove, (s)how inventory, (q)uit: ";
        std::cin >> userInput;
        if ( userInput[0] == 'a' || userInput[0] == 'A' ) {
            std::cout << "nEnter (b)ook or (p)roduce: ";
            std::cin >> userInput;
            if ( userInput[0] == 'b' || userInput[0] == 'B' ) {
                std::string strName;
                std::string strAuthor;
                float price = 0;
                std::cout << "nEnter the name of the book. ";
                std::getline( std::cin, strName ); // For Some Reason I have To Add This Twice
                std::getline( std::cin, strName );
                std::cout << "nEnter the book's author. ";
                std::getline( std::cin, strAuthor );
                std::cout << "nEnter the price in US Dollars. ";
                std::cin >> price;
                inventory.addBook( strName, strAuthor, price );
            } else if ( userInput[0] == 'p' || userInput[0] == 'P' ) {
                std::string strName;
                std::string strExpiration;
                float price = 0;
                std::cout << "nEnter the type of produce. ";
                std::getline( std::cin, strName ); // For Some Reason I have To Add This Twice
                std::getline( std::cin, strName );
                std::cout << "nEnter the expiration date. ";
                std::getline( std::cin, strExpiration );
                std::cout << "nEnter the price in US Dollars. ";
                std::cin >> price;
                inventory.addProduce( strName, strExpiration, price );          
            } else {
                std::cout << "nInvalid Entryn";
            }
            system( "cls" ); // If on windows and using win32 console
            continue;
        } else if ( userInput[0] == 'r' || userInput[0] == 'R' ) {
            // Clear The Screen, Show The Inventory Then Ask User Which Item To Remove
            system( "cls" ); // If on windows and using win32 console
            inventory.showInventory();
            std::cout << "nWhich item would you like to remove (b)ook or (p)roduce? ";
            std::cin >> userInput;
            StoreItem::ItemType type;
            if ( userInput[0] == 'b' || userInput[0] == 'B' ) {
                if ( inventory.isBookListEmpty() ) {
                    std::cout << "nThere are no entries availabe to remove. ";
                    continue;
                } else {
                    type = StoreItem::ITEM_BOOK;
                }
            } else if ( userInput[0] == 'p' || userInput[0] == 'P' ) {
                if ( inventory.isProduceListEmpty() ) {
                    std::cout << "nThere are no entries available to remove. ";
                    continue;
                } else {
                    type  = StoreItem::ITEM_PRODUCE;
                }
            } else {
                std::cout << "nInvalid Typen";
            }
            std::string strName;
            unsigned idx;
            std::cout << "nEnter name of product you wish to remove. ";
            std::getline( std::cin, strName ); // For Some Reason I have To Add This Twice
            std::getline( std::cin, strName );
            std::cout << "nEnter item number of this type you wish to remove. ";
            std::cin >> idx;
            inventory.removeItemFromIventory( type, strName, idx );
            continue;
        }  else  if ( userInput[0] == 's' || userInput[0] == 'S' ) {
            system( "cls" ); // If on windows and using win32 console
            inventory.showInventory();
            continue;
        } else if ( userInput[0] == 'q' || userInput[0] == 'Q' ) {
            quit = true;
            break;  
        } else {
            std::cout << "nInvalid Entryn";
            continue;
        }           
    } // while
    std::cout << "nPress any key to quit" << std::endl;
    _getch();
    return 0;
} // main

少数问题:1.)priceInDollars未正确初始化2.)totalInvPriceInDollars需要是静态

以下代码修复了问题:

#include <iostream>
#include <string>
#include <vector>
#include <sstream>
using namespace std;
int totalInvPriceInDollars = 0 ;
class Inventory {
public:
    Inventory(): priceInDollars(0) {};
    void SetSumInv(int prcInDllrs, int individualquantity) {
        priceInDollars = priceInDollars + (prcInDllrs * individualquantity);
        totalInvPriceInDollars = totalInvPriceInDollars + priceInDollars;
    }
    void SetItemPrice(int whatever) {
        itemsPrice = whatever;
    }
    void SetName(string nm)
    {
        name = nm;
    };
    void SetQuantity(int qnty)
    {
        quantity = qnty;
    };
    void SetAuthor(string athr) {
        author = athr;
    }
    void SetExpiration(string expir)
    {
        expiration = expir;
    };
    virtual void Print(){
        cout << name << " x" << quantity << " for: $" << itemsPrice; //" (Expires: " << expiration << ")";
        if (expiration.size() != 0) {
            cout << " (Expires: " << expiration << ")" << endl;
        }
        else {
            cout << " (Author: " << author << ")" << endl;
        }
    }
    void PrintInventory(vector<Inventory*> inventory) {
        unsigned int i = 0;
        if (inventory.size() == 0) {
            cout << "No items to print." << endl;
        }
        else {
            for (i = 0; i<inventory.size(); ++i) {
                cout << i << " - ";
                inventory.at(i)->Print();
            }
            cout << "Total inventory value: " << totalInvPriceInDollars;
        }
        return;
    }
    void AddItemToInventory()
    {
    }
    vector<Inventory*> AddProduceToInventory(vector<Inventory*> inventory)
    {
        Inventory* prdc;
        string usrInptName = "";
        string usrInptQntyStr = "";
        istringstream inSS;
        istringstream inDD;
        int usrInptQnty = 0;
        string usrInptExpr = "";
        string usrInptPrcStr = "";
        int usrInptPrc = 0;
        int ItemCost = 0;
        cout << "Enter name of new produce: ";
        getline(cin, usrInptName);
        SetName(usrInptName);
        cout << "Enter quantity: ";
        getline(cin, usrInptQntyStr);
        inSS.str(usrInptQntyStr);
        inSS >> usrInptQnty;
        inSS.clear();
        SetQuantity(usrInptQnty);
        cout << "Enter expiration date: ";
        getline(cin, usrInptExpr);
        SetExpiration(usrInptExpr);
        cout << "Enter the price per item: $";
        getline(cin, usrInptPrcStr);
        inDD.str(usrInptPrcStr);
        inDD >> usrInptPrc;
        inDD.clear();
        SetItemPrice(usrInptPrc);
        ItemCost = (usrInptPrc * usrInptQnty);
        prdc = new Inventory;
        prdc->SetName(usrInptName);
        prdc->SetQuantity(usrInptQnty);
        prdc->SetExpiration(usrInptExpr);
        prdc->SetSumInv(usrInptPrc, usrInptQnty);
        prdc->SetItemPrice(usrInptPrc);
        inventory.push_back(prdc);
        return inventory;
    }
    void AddBookToInventory()
    {
    }
    vector<Inventory*> AddBookToInventory(vector<Inventory*> inventory) {
        Inventory* prdct;
        string usrInptName = "";
        string usrInptQntyStr = "";
        istringstream inSS;
        int usrInptQnty = 0;
        string usrInptAthr = "";
        string usrInptPrcStr = "";
        int usrInptPrc = 0;
        istringstream inDD;
        int sum = 0;
        int ItemCost = 0;
        cout << "Enter name of new book: ";
        getline(cin, usrInptName);
        cout << "Enter quantity: ";
        getline(cin, usrInptQntyStr);
        inSS.str(usrInptQntyStr);
        inSS >> usrInptQnty;
        inSS.clear();
        cout << "Enter author: ";
        getline(cin, usrInptAthr);
        cout << "Enter the price per item: $";
        getline(cin, usrInptPrcStr);
        inDD.str(usrInptPrcStr);
        inDD >> usrInptPrc;
        inDD.clear();
        ItemCost = (usrInptPrc * usrInptQnty);
        prdct = new Inventory;
        prdct->SetName(usrInptName);
        prdct->SetQuantity(usrInptQnty);
        prdct->SetSumInv(usrInptPrc, usrInptQnty);
        prdct->SetAuthor(usrInptAthr);
        prdct->SetItemPrice(usrInptPrc);
        inventory.push_back(prdct);

        return inventory;
    }
    void UpdateItemQtyInventory()
    {}
    //This is the update function in which we can change how many items a certain purchase has
    vector<Inventory*> UpdateItemQtyInInventory(vector<Inventory*> inventory) {
        string usrIndexChoiceStr = "";
        unsigned int usrIndexChoice = 0;
        istringstream inSS;
        string usrInptQntyStr = "";
        int usrInptQnty = 0;

        if (inventory.size() == 0) {
            cout << "No items to update." << endl;
        }
        else {
            PrintInventory(inventory);
            do {
                cout << "Update which item #: ";
                getline(cin, usrIndexChoiceStr);
                inSS.str(usrIndexChoiceStr);
                inSS >> usrIndexChoice;
                inSS.clear();
            } while (!(usrIndexChoice < inventory.size()));
            cout << "Enter new quantity: ";
            getline(cin, usrInptQntyStr);
            inSS.str(usrInptQntyStr);
            inSS >> usrInptQnty;
            inSS.clear();
            inventory.at(usrIndexChoice)->SetQuantity(usrInptQnty);
        }
        return inventory;
    }
    void RemoveItemFromInventory()
    {}
    //Here we will be removing an entire item from the inventory
    vector<Inventory*> RemoveItemFromInventory(vector<Inventory*> inventory) {
        istringstream inSS;
        string usrIndexChoiceStr = "";
        unsigned int usrIndexChoice = 0;
        string usrInptQntyStr = "";
        if (inventory.size() == 0) {
            cout << "No items to remove." << endl;
        }
        else {
            PrintInventory(inventory);
            do {
                cout << "Remove which item #: ";
                getline(cin, usrIndexChoiceStr);
                inSS.str(usrIndexChoiceStr);
                inSS >> usrIndexChoice;
                inSS.clear();
            } while (!(usrIndexChoice < inventory.size()));
            inventory.erase(inventory.begin() + usrIndexChoice);
        }
        return inventory;
    }
    void GetTotalValueAsPrice()
    {
    }
protected:
    string name;
    int    quantity;
    int priceInDollars ;
    int totalCost;
    int itemsPrice;
    string expiration;
    string author;
};
int main() {
    vector<Inventory*> INVENTORY;
    string usrInptOptn = "default";
    string usrInptOptn2 = "default";
    Inventory update;
    while (true) {
        // Get user choice
        cout << "nEnter (p)rint, (a)dd, (u)pdate, (r)emove, or (q)uit: ";
        getline(cin, usrInptOptn);
        // Process user choice
        if (usrInptOptn.size() == 0) {
            continue;
        }
        else if (usrInptOptn.at(0) == 'p') {
            update.PrintInventory(INVENTORY);               //Different! 
        }
        else if (usrInptOptn.at(0) == 'a') {///I don't know what the difference is between the three slashes and the two, but they are different!
            cout << "nEnter (b)ook or (p)roduce: ";
            getline(cin, usrInptOptn2);
            if (usrInptOptn2.at(0) == 'b') {
                INVENTORY = update.AddBookToInventory(INVENTORY);                                   //Supposed to look like: INV = AddItem...(INV);
            }
            else if (usrInptOptn2.at(0) == 'p') {
                INVENTORY = update.AddProduceToInventory(INVENTORY);
            }
            else
            {
                continue;
            }
        }
        else if (usrInptOptn.at(0) == 'u') {
            INVENTORY = update.UpdateItemQtyInInventory(INVENTORY);
        }
        else if (usrInptOptn.at(0) == 'r') {
            INVENTORY = update.RemoveItemFromInventory(INVENTORY);
        }
        else if (usrInptOptn.at(0) == 'q') {
            cout << "nGood bye." << endl;
            break;
        }
    }
    return 0;
}