簡體   English   中英

C ++對函數和向量感到困惑

[英]C++ Confused about functions and vectors

希望這將是我一段時間以來的最后一個問題。

我對為什么我的功能無法正常工作感到有些困惑。 這是我的代碼(稍后再解釋):

#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;
}

所以現在。 在我的班級清單,公共:void SetSumInv中,該程序執行的操作是獲取用戶輸入,並匯總所有內容,因此在打印時,應打印清單,然后再打印清單的總和。價值(以美元為單位)。 我已經嘗試運行此程序,但它不會顯示庫存值的總和。 怎么了 我不知道這個。

謝謝!

解剖代碼后; 我花了很多時間來清理其中的一些東西。 我沒有時間搜索您的錯誤,但是我能夠做的是稍微整理一下您的課程,以便閱讀時更友好。 我對您的類的某些函數調用做了一些修改,這些注釋在注釋中進行了解釋。 我還刪除了您在類中聲明的所有空函數。 我還更改了類命名約定的外觀(僅用戶首選項)

庫存

#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

庫存文件

#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並沒有成堆的代碼行; 始終使main.cpp簡短易行是一個好習慣,因為這是主可執行文件開始的地方。 我創建了清單類,並將其放在*.h*.cpp文件中的自己的模塊中。 我也將其聲明與定義或實現分開。 如果其他人正在查看您的源代碼以使用它,則這種方式; 他們不必確切地知道該功能的工作原理,而只需要知道它應該做什么。 接口或*.h文件應該告訴您有關類對象及其使用方法的所有信息。 這也使構建過程更快捷,因為僅當您在其中進行了某些更改而不是重新構建整個解決方案時,才需要編譯此類的*.cpp文件。

現在,在某些情況下,您可能希望在頭文件中具有該實現,而在某些情況下,您不得不選擇它。 您可能希望將實現包含在頭文件中的情況是,如果您的方法被聲明為inline或者您正在創建僅頭文件的庫。 您可能別無選擇,只能在頭文件中進行選擇的情況是,如果要創建class templatesfunction templates但是當您同時擁有inline member functionsclass template member functionsfunction templates這兩種類型時,通常是*.inl聯文件或*.inl ,您可以在類聲明的外部且在#endif標頭保護之前使用#include指令包含此文件; 如果您只使用#pragma once而不是#ifndef #define #endif那么在類的聲明之后就可以使用它。

一旦您開始擁有自己喜歡的恆定代碼結構; 調試和發現錯誤將變得更加容易。

在您的問題之外,我想我已經注意到您引入的另一個錯誤,您可能會或可能不會注意到; 我認為您的程序可能存在內存泄漏!

我希望這可以為您提供幫助。 如果我在接下來的幾天有機會; 我可能會繼續嘗試調試您的代碼或嘗試以一種稍微更優雅的方式重寫您的程序。 如果確實解決了,我會將其發布為另一個答案。

我已經編寫了用戶要求的程序版本。 我花了一些時間來解決錯誤並確保它能按預期工作。 這並不意味着它完全沒有錯誤。 如果有人碰巧發現了任何錯誤,請隨時評論並列出所有錯誤,以便我進行修復並進行適當的編輯。

該程序使用C ++編寫,使用Win32控制台應用程序和VS 2015編譯和構建。

我在這里所做的是創建一個小類層次結構。 StoreItem類是一個抽象基類,這意味着您不能直接創建此類型的對象,因為其構造函數受到保護。 從該基類繼承的任何類對象都可以公開構造。 我這樣做是因為不同的產品類型可能具有不同的信息。

我了解了所有產品類型的共同點,並使用受保護的成員和公共訪問功能將該信息存儲到基類中。 基類中唯一的私有成員是繼承類在構造時的Type 這些只是包含數據和方法的對象。 Inventory類是存儲和刪除項目,計算總計並打印其清單的大部分工作。

我以這種方式進行了設計,以使StoreItem及其繼承的類與iostream對象沒有任何依賴關系。 庫存類僅在其打印方法中使用std::cout對象。

與輸入或std::cin對象一起使用的唯一代碼部分位於while循環工作的main函數內。

具有這樣的結構,可以使這些類模塊化或可重用。 這也使添加其他類型或存儲項目變得容易。 您將必須創建另一個派生自StoreItem的類,在Enumerated類型中添加Add,然后重復在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

書本

#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

Produce.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

庫存

#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

庫存文件

#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 Entry\n";
            }
            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 Type\n";
            }

            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 Entry\n";
            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;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM