2

I am trying to use init() to start my program but it tells me that there is "no appropriate default constructor available" for this line MerkelMain app{}; of the main.cpp. What do I need to add to make it work? Am I missing a constructor?

main.cpp

#include "OrderEntry.h"
#include "MerkelMain.h"
#include "CSVReader.h"

int main()
{
    MerkelMain app{};
    app.init();
}

MerkelMain.cpp

#include <iostream>
#include <vector>
#include "OrderEntry.h"
#include "MerkelMain.h"
#include "OrderFood.h"

MerkelMain::MerkelMain(OrderFood _orders)
: orders (_orders)
{

}

void MerkelMain::init()
{
    std::string input;

    while (true)
    {
        printMenu();    
        input = getUserOption();
        processUserOption(input);
    }
}

void MerkelMain::printMenu()
{
    std::cout << "Welcome to Restaurant Firebird" << std::endl;
    std::cout << "a . Order a plate of chicken rice" << std::endl;
    std::cout << "b . Order a plat for wanton noodles" << std::endl;
    std::cout << "c . Order a cup of Coffee" << std::endl;
    std::cout << "d . Order a cup of Tea" << std::endl;
    std::cout << "e . Repeat Order" << std::endl;
    std::cout << "f . Exit Menu" << std::endl;
    std::cout << "------------------------------------" << std::endl;
    std::cout << "Type an option from a-f" << std::endl;
}


std::string MerkelMain::getUserOption()
{
    std::string choice;
    std::cin >> choice;
    return choice;
}

int MerkelMain::getQuantity()
{
    int qty;
    std::cin >> qty;
    return qty;
}

void MerkelMain::processUserOption(std::string choice)
{
   std::endl(std::cout);

   if (choice == "a")
    {
        std::cout << "How many plates of chicken rice would you like to order?" << std::endl;
        OrderType order = OrderType::chickenrice;
        int qty = getQuantity();
        std::endl(std::cout);
        std::cout << "Thank you for your order of " << qty << " plates of Chicken Rice." << std::endl;
        std::endl(std::cout);
        OrderEntry food_order = OrderEntry(qty, order);
        orders.orderQueue.push_back(std::move(food_order));
    }
    if (choice == "b")
    {
        std::cout << "How many plates of wanton noodles would you like to order?" << std::endl;
        OrderType order = OrderType::wantonnoodle;
        int qty = getQuantity();
        std::endl(std::cout);
        std::cout << "Thank you for your order of " << qty << " plates of Wanton Noodles." << std::endl;
        std::endl(std::cout);
        OrderEntry food_order = OrderEntry(qty, order);
        orders.orderQueue.push_back(std::move(food_order));
    }
    if (choice == "c")
    {
        std::cout << "How many cups of Coffee would you like to order?" << std::endl;
        OrderType order = OrderType::coffee;
        int qty = getQuantity();
        std::endl(std::cout);
        std::cout << "Thank you for your order of " << qty << " cups of Coffee." << std::endl;
        OrderEntry food_order = OrderEntry(qty, order);
        orders.orderQueue.push_back(std::move(food_order));
    }
    if (choice == "d")
    {
        std::cout << "How many cups of Tea would you like to order?" << std::endl;
        OrderType order = OrderType::tea;
        int qty = getQuantity();
        std::endl(std::cout);
        std::cout << "Thank you for your order of " << qty << " cups of Tea." << std::endl;
        std::endl(std::cout);
        OrderEntry food_order = OrderEntry(qty, order);
        orders.orderQueue.push_back(std::move(food_order));
    }
    if (choice == "e")
    {
        std::cout << "You have ordered: " << std::endl;

        for (unsigned int i = 0; i < orders.orderQueue.size(); ++i)
        {
            std::cout << orders.orderQueue[i].qty << " " << OrderEntry::orderTypeToString(orders.orderQueue[i].orderType) << std::endl;
        }
        std::endl(std::cout);
    }
    if (choice == "f")
    {
        std::cout << "Thank you and see you again soon." << std::endl;
        
    }
}

MerkelMain.h

#pragma once
#include <iostream>
#include <vector>
#include "CSVReader.h"
#include "OrderEntry.h"
#include "OrderFood.h"

class MerkelMain
{
    public:
        MerkelMain(OrderFood _orders);
        void init();
    private:
        void printMenu();
        std::string getUserOption();
        int getQuantity();
        void processUserOption(std::string choice);

        OrderFood orders;
        OrderFood orderFood{"Rest_Order.csv"};
};
ahmadalibin
  • 133
  • 8
  • 4
    Well, your only constructor takes an `OrderFood` argument, and you're not passing one, so... Why does it do that? – molbdnilo Nov 11 '20 at 08:08

2 Answers2

1

In your main function you are trying to instantiate an instance of MerkelMain by calling its default constructor.

MerkelMain app{};

However, since you have a user-defined constructor MerkelMain(OrderFood _orders) the compiler will no longer automatically generate a default constructor.

In order to make it work you will need to manually define a default constructor or pass an instance of OrderFood when instantiating the MerkelMain.

JonatanE
  • 941
  • 7
  • 19
  • I'm still a beginner at this. What should I define the default constructor as? – ahmadalibin Nov 11 '20 at 08:32
  • You could define it like this: `MerkelMain() = default;` to have the compiler generate it for you. This will make it compile successfully. However, you will probably need to add a real implementation. Ted Lyngmo's comment might point you in the right direction. – JonatanE Nov 11 '20 at 08:45
1

You are trying to use the default constructor when you do MerkelMain app{}; but your MerkelMain class doesn't have a default constructor.

One possible way would be to add a default constructor that delegates to your current converting constructor to read from what looks like a default csv file.

.hpp

class MerkelMain
{
    public:
        MerkelMain();                    // added default constructor
        MerkelMain(OrderFood _orders);   // leave your current converting ctor as-is
        void init();
    private:
        void printMenu();
        std::string getUserOption();
        int getQuantity();
        void processUserOption(std::string choice);

        OrderFood orders;
        OrderFood orderFood{"Rest_Order.csv"}; // this should probably be removed
};

.cpp

// add this without changing the current converting constructor:
MerkelMain::MerkelMain() :
    MerkelMain(OrderFood{"Rest_Order.csv"}) // delegate to the converting constructor
{}
Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108
  • Ok I added those in and now I get the errors `'MerkelMain::MerkelMain(MerkelMain &&)': cannot convert argument 1 from 'const char [15]' to 'OrderFood'` and also `no instance of constructor "MerkelMain::MerkelMain" matches the argument list` – ahmadalibin Nov 11 '20 at 10:07
  • @ahmadalibin Ok, I updated it. Can you put the definition of the `OrderFood` class in the question if this doesn't work please? – Ted Lyngmo Nov 11 '20 at 10:09
  • @ahmadalibin And please, can you explain what the `orderFood` member variable is used for? Why do you have two `OrderFood` instances in `MerkelMain`? – Ted Lyngmo Nov 11 '20 at 10:19
  • Yes. It works perfectly now. Thank you very much. About the OrderFood, I was just following this person's solution to my other question about accessing vector from the OrderFood class. [link](https://stackoverflow.com/questions/64780932/store-data-in-a-vector-from-another-class) – ahmadalibin Nov 11 '20 at 10:23