4 of 5
New Implementation
user avatar
user avatar

Class Iteam: Answer to one of the unsolved Stack Overflow Qes

I would like to improve my skill on C++ concepts and I came across the following question in StackOverflow, which has been directly asked by a StackOverflow-user without any preliminary attempts.(unfortunately, I have only the image of the question, since the actual post was an unsolved question, it has been removed from the site by the user itself) . Any tips or comments to optimize or improve the code and the correctness issues of the solution would be most welcome. .

#include <iostream>
#include <string>
#include <unordered_map>

/** Class which has been asked in the question. In short Iteam class will act like
    a struct for iteamList class, since I have declared iteamList class as a friend
    of Iteam class **/
class iteamList; // forward delaration of iteamList class
class Iteam
{
private:
    int m_code;
    int m_price;
    int m_quantity;
public:
    Iteam()                                     // Defualt
        :m_code(0), m_price(0), m_quantity(0)
        {}
    Iteam(const int& code, const  int& price, const int& quntity)// Parameterized
        :m_code(code), m_price(price), m_quantity(quntity)
        {}
    Iteam(const Iteam& rhs)                     // Copy
        :m_code(rhs.m_code), m_price(rhs.m_price), m_quantity(rhs.m_quantity)
        {}
    Iteam(Iteam&& rhs)                          // Move
        :m_code(rhs.m_code), m_price(rhs.m_price), m_quantity(rhs.m_quantity)
        {}
    ~Iteam()     {}

    //(i) input the data members
    inline void inputData()
    {
        std::cout<<"Iteam code :"; std::cin>>m_code;
        std::cout<<"Iteam price :"; std::cin>>m_price;
        std::cout<<"Iteam quantity :"; std::cin>>m_quantity;
    }
    // life would be easy after making this statement :) !
    friend iteamList;
    //(ii) to display the data members
    friend std::ostream& operator<<(std::ostream& output, const Iteam& obj);
};
std::ostream& operator<<(std::ostream& output, const Iteam& obj)
{
    return output<<"Iteam code = "<<obj.m_code
                <<"\t price = "<<obj.m_price
                <<"\t quantity = "<<obj.m_quantity<<"\n";
}
/******************************************************************************/
/** Implementation of the main class which is independent of the above one.
    It can access all members of above class if it has instantiated an object of it.
    I have used STL std::unordered_map to store the Items which will be easier to
    look up(with an O(1)) at the time of queries of deletion.**/

class iteamList
{
private:
    int m_totalStockValue = 0;
    std::unordered_map<int, Iteam> m_iteamMap;
private:
    // (iii) appending iteam to the list
    inline void AppendIteams(const int& userInput_n)
    {
        for(auto i=0; i<userInput_n; ++i)
        {
            Iteam obj;
            obj.inputData();
            std::cout << obj << std::endl;
            m_iteamMap.emplace(obj.m_code, obj);
        }
    }
public:
    iteamList() = default;

    iteamList(const int& userInput_n)
    {
        m_iteamMap.reserve(userInput_n);
        AppendIteams(userInput_n);
    }
    ~iteamList(){}

    // (iv) delete the iteam from the list
    void deleteIteam(const int& code)
    {
        if(m_iteamMap.find(code) != m_iteamMap.cend())
        {
            std::cout << m_iteamMap[code] << " has been deleted!\n";
            m_iteamMap.erase(m_iteamMap.find(code));
        }
        else
            std::cout <<"Invalid Iteam code!" << std::endl;
    }
    // (v) total value of the stock
    void claculateStockValue()
    {
        m_totalStockValue = 0;
        for(const auto &it:m_iteamMap)
            m_totalStockValue += (it.second.m_price * it.second.m_quantity);

        std::cout <<m_totalStockValue<< std::endl;
    }
};
/**********************************************************************************/
int main()
{
    int number;
    std::cout <<"Enter total number of iteams : ";
    std::cin>>number;

    iteamList obj(number);

    std::cout <<"Total Value of stock = ";
    obj.claculateStockValue();

    int code;
    std::cout <<"Enter code to delete the iteam : ";
    std::cin>>code;
    obj.deleteIteam(code);

    std::cout <<"Total Value of stock = ";
    obj.claculateStockValue();

    return 0;
}

Edit: New Implementation: As per the comments I received, I have re-written the above classes as follows. However a few comments on it:

  1. Suggestion for getters and setters: I have tried to make setters but for getters, I have no idea, how they actually work for a pure abstract class, since we can't instantiate the class(and call the member function like, object.getSomething()). I really would like to receive comment on this.
  2. I would like to const& always, whenever it's possible because, it will work for both lvalues and rvalues, which helps not to have extra coding for rvalues separately(just my point of view and habits). I am not saying that it should be always like that(of course there must be some cases where we should have either lvalue calls or rvalue calls.) But in this particular case(constructors and class methods), it would be okay to use.

here is the complete code: https://ideone.com/UonX7I

#include <iostream>
#include <string>
#include <unordered_map>
#include <memory>

/**************** Item: defined as a pure abstract class ************************ **/

class Item
{
protected:
    int m_code;
    int m_price;
    int m_quantity;
public:
    Item() = default;

    void setCode(const int& code)   {   m_code = code;  }
    void setPrice(const int& price)   {   m_price = price;  }
    void setQuantity(const int& quantity)   {   m_quantity = quantity;  }

    /*const int& getCode()const { return m_code;  }
    const int& getPrice()const { return m_price;  }
    const int& getQuantity()const { return m_quantity;  }*/

    virtual int calculateStockValue() = 0;
    virtual ~Item(){ };
};

/** ItemTable : inherits from Item, to store code - price - quantity to hash table **/

class ItemTable: public Item
{
private:
    std::unordered_map<int, std::pair<int,int>> m_itemTable;
public:
    ItemTable() = default;
    //(ii) to display the data members according to the item code
    void displayItem(const int& code)
    {
        if(m_itemTable.find(code) != m_itemTable.cend())
        {
            auto it = m_itemTable.find(code);
            std::cout << "Item code = " << it->first;
            std::cout << "\t price = " << it->second.first;
            std::cout << "\t quantity = " << it->second.second << std::endl;
        }
        else
            std::cout << "Invalid Item code!" << std::endl;
    }
    // (iii) appending Item to the list
    void appendItem(const int& code, const  int& price, const int& quantity)
    {
        //(i) input the data members
        setCode(code);
        setPrice(price);
        setQuantity(quantity);
        m_itemTable.emplace(m_code, std::make_pair(m_price, m_quantity));
    }
    // (iv) delete the Item from the list
    void deleteItem(const int& code)
    {
        if(m_itemTable.find(code) != m_itemTable.cend())
        {
            std::cout << "The item with code: " << code
                    << " has been deleted successfully!" <<std::endl;
            m_itemTable.erase(m_itemTable.find(code));
        }
        else
            std::cout << "Invalid Item code!" << std::endl;
    }
    // (v) total value of the stock
    virtual int calculateStockValue() override
    {
        int m_totalStock = 0;
        for(const auto &it:m_itemTable)
            m_totalStock += (it.second.first * it.second.second);

        return m_totalStock;
    }
    virtual ~ItemTable(){ };
};

/********************* main ******************************/

int main()
{
    int number;
    int code;
    std::unique_ptr<ItemTable> obj = std::make_unique<ItemTable>();

    std::cout << "Enter total number of Items : ";  std::cin >> number;

    for(int i = 0; i<number; ++i)
    {
        int code, price, quantity;
        std::cout << i+1 << ": Enter the Item code = "; std::cin >> code ;
        std::cout << i+1 << ": Enter the Item price = "; std::cin >> price ;
        std::cout << i+1 << ": Enter the Item quantity = "; std::cin >> quantity ;
        obj->appendItem(code, price, quantity);
    }

    std::cout << "Total Value of stock = " << obj->calculateStockValue() << std::endl;

    std::cout << "Enter code of the Item to be displayed: "; std::cin >> code;
    obj->displayItem(code);

    std::cout << "Enter code to delete the Item : ";         std::cin >> code;
    obj->deleteItem(code);

    std::cout << "Total Value of stock = " << obj->calculateStockValue() << std::endl;

    return 0;
}
user164525