【问题标题】:How can I get one class's vector to push back data from vectors in two other classes?如何让一个类的向量从其他两个类的向量中推回数据?
【发布时间】:2020-08-09 13:33:11
【问题描述】:

给定 A、B 和 C 类,我想知道如何将属于 A 和 B 类的向量的分量推回属于 C 类的一个向量。

例如,在下面的代码中,我有一个用于订购比萨饼的简单程序。该程序允许用户在系统中输入新客户和新的比萨饼类型,然后程序使用这些数据将客户和比萨饼向量推回。

neworder() 函数要求用户输入构成订单的客户和比萨饼的 ID 号。然后程序搜索这些 ID 号,如果匹配,它会要求用户确认这些 ID 代表正确的客户和披萨。

一旦用户确认订单是正确的,我想推回 Order 类的订单向量,以包含比萨饼向量和客户向量的分量,这些分量对应于用户提供的 ID。

例如,如果用户输入 ID 0 0 并确认这是正确的选择,我希望程序用 both 存储在 x.pizzas[ 中的信息来推送订单向量0] (0, "wheat", "amatriciana", "provolone", "squid") 存储在 y.customers[0] {0, "Bjarne", "Stroustrup"} 的信息. (注意ID号对应向量位置。)

最好的方法是什么?一如既往地感谢您的帮助!

//Test to see how I can get a vector in one class to store elements from vectors from two other classes

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

class Pizza
{
public:
    string crust;
    string sauce;
    //Mmm... string cheese
    string cheese;
    string topping;
    int pizzaid;
    vector<Pizza> pizzas;
    void addtomenu();

    Pizza(int a, string b, string c, string d, string e)
        : pizzaid{a}, crust{b}, sauce{c}, cheese{d}, topping{e} {}
};

class Customer
{
public:
    string firstname;
    string lastname;
    int customerid;
    vector<Customer> customers;
    void addcustomer();
    Customer(int a, string b, string c)
        : customerid{a}, firstname{b}, lastname{c} {}
};

class Order
{
public:
    Pizza orderedpizza;
    Customer customerordering;
    int orderid;
    vector<Order> orders;
    void neworder();
    void data();
    Order(Pizza a, Customer b)
        : orderedpizza{a}, customerordering{b} {}
};

//I added in these placeholder objects so that I could run functions/push back vectors that belong to these functions' classes. I'm not sure whether there is a more sophisticated way to do this.
//I used negative integers just in case positive ones would interfere with actual pizza/customer IDs.
Pizza x{-1, " ", " ", " ", " "};
Customer y{-1, " ", " "};
Order z{x, y};

void Pizza::addtomenu()
{
    cout << "Please enter the crust, sauce, cheese, and topping that this pizza will have, all separated by spaces.\n";
    cin >> crust >> sauce >> cheese >> topping;
    pizzaid = pizzas.size();
    x.pizzas.push_back(Pizza{pizzaid, crust, sauce, cheese, topping});
    cout << "The pizza has been added.\n";
}

void Customer::addcustomer()
{
    cout << "Please enter the first and last name of the customer, separated by spaces.\n";
    cin >> firstname >> lastname;
    customerid = customers.size();
    y.customers.push_back(Customer{customerid, firstname, lastname});
    cout << "The customer has been added.\n";
}

void Order::neworder()
{
    int tempcustomerid;
    int temppizzaid;
    bool trueflag1 = 0;
    bool trueflag2 = 0;
    string entry;
    cout << "Please enter the customer's ID, followed by the ID of the pizza being ordered. Separate the two with spaces.\n";
    if (cin >> tempcustomerid >> temppizzaid)
    {
        for (int d = 0; d < y.customers.size(); d++)
        {
            if (tempcustomerid == y.customers[d].customerid)
            {
                trueflag1 = 1;
                tempcustomerid = d;
            }
        }

        if (trueflag1 == 0)
        {
            cin.clear();
            cin.ignore(1000, '\n');
            cout << "That ID does not match any customer in the system.\n";
            return;
        }

        for (int e = 0; e < x.pizzas.size(); e++)
        {
            if (temppizzaid == x.pizzas[e].pizzaid)
            {
                cin.clear();
                cin.ignore(1000, '\n');
                trueflag2 = 1;
                temppizzaid = e;
            }
        }

        if (trueflag2 == 0)
        {
            cout << "That ID does not match any pizza in the system.\n";
            return;
        }

        {
            cout << "The following customer: " << y.customers[tempcustomerid].customerid << " " << y.customers[tempcustomerid].firstname << " " << y.customers[tempcustomerid].lastname << " ";
            cout << "will be ordering the following pizza: " << x.pizzas[temppizzaid].pizzaid << " " << x.pizzas[temppizzaid].crust << " " << x.pizzas[temppizzaid].sauce << " " << x.pizzas[temppizzaid].cheese << " " << x.pizzas[temppizzaid].topping << ".\n";
            cout << "Is that correct? If yes, press 1; if no, press 0.\n";
            cin >> entry;
            if (entry == "1")
            {
                //Here, I would like to push back my orders vector to include the contents of y.customers[tempcustomerid] and y.pizzas[temppizaid]. What would be the best way to do this?

                cout << "The order has been placed.\n";
            }
            else
            {
                cout << "Order canceled.\n";
                return;
            }
        }
    }
    else
    {
        cin.clear();
        cin.ignore(10000, '\n');
        cout << "Please enter your input in integer form.\n";
    }
}

void Order::data()
{
    cout << "Pizzas entered into system so far:\n";
    for (int d = 0; d < x.pizzas.size(); d++)
    {
        cout << x.pizzas[d].pizzaid << " " << x.pizzas[d].crust << " " << x.pizzas[d].sauce << " " << x.pizzas[d].cheese << " " << x.pizzas[d].topping << "\n";
    }

    cout << "Customers entered into system so far:\n";
    for (int d = 0; d < y.customers.size(); d++)
    {
        cout << y.customers[d].customerid << " " << y.customers[d].firstname << " " << y.customers[d].lastname << "\n";
    }
}

int main()

{
    //These two push_back functions are added to create test items for debugging purposes.
    x.pizzas.push_back(Pizza{0, "wheat", "amatriciana", "provolone", "squid"});
    y.customers.push_back(Customer{0, "Bjarne", "Stroustrup"});

    string entry;
    while (true)
    {
        cout << "Welcome to the Pizza Orderer 5000. To enter a new customer, enter addcustomer. To enter a new pizza to the menu, enter addtomenu. To enter a new order, enter order. To list all data in the system, enter data. To quit, enter quit.\n";
        cin >> entry;
        if (entry == "addcustomer")
            y.addcustomer();
        else if (entry == "addtomenu")
            x.addtomenu();
        else if (entry == "order")
            z.neworder();
        else if (entry == "data")
            z.data();
        else if (entry == "quit")
            break;
        else
        {
            cin.clear();
            cin.ignore(10000, '\n');
            cout << "I'm sorry, that input was not recognized. Please try again.\n";
        }
    }
}

【问题讨论】:

  • 听起来像XY Problemstd::mapunordered_map 的关键是客户,数据是他们想要的订单听起来更可行。此外,您不需要在这些类中存储向量。
  • 您需要一个额外的类 Order,它具有 Customer 和 Pizza 的字段,并将该对象向下推到另一个向量上。同时将向量从 Customer 和 Pizza 类中讨论出来……它们不属于在那里。
  • @PaulMcKenzie 嗯,很可能就是这样。绝对开放以替代方式来跟踪订单交易。我目前正在阅读《编程:使用 C++ 的原则和实践》的第 10 章,看起来地图将在第 21 章中介绍。也许一旦我到达那里,我会对这类情况的最佳实践有更好的理解。
  • 看起来客户id 是独一无二的。那将是地图中的关键。地图中的数据将是描述客户订单的类。客户 ID 及其订单的查找时间也将最小化,而不必遍历向量。
  • @PaulMcKenzie 谢谢,一旦我进入地图部分,我会尽量记住这一点。 Pizzaid int 在比萨饼中也是独一无二的,那么它也可以是一个键吗?或者地图中有两个键? (我想我正在考虑电子表格上的行/列,其中订单可能是客户行和披萨列的交集。但也许我对 C++ 中的地图看起来有什么误解。”跨度>

标签: c++ function class oop vector


【解决方案1】:

PaulMckenzie 的评论启发了我解决这个问题,方法是使用每个订单的 customerid 和 Pizzaid (而不是 Pizza 和 Customer 类本身)推回订单向量。然后,订单向量中的信息可用于从比萨饼和顾客向量中再现​​信息。

我没有将 Pizzas 的 int Pizzaid 和 Customer 的 int customerid 作为 Order 类的成员包括在内,而是复制了它们。我想会有一种方法可以使用原始整数(如果是这样,请告诉我)。

这是修改后的代码,还有一些额外的 cmets:

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

class Pizza
{
public:
    string crust;
    string sauce;
    //Mmm... string cheese
    string cheese;
    string topping;
    int pizzaid;
    vector<Pizza> pizzas;
    void addtomenu();

    Pizza(int a, string b, string c, string d, string e)
        : pizzaid{a}, crust{b}, sauce{c}, cheese{d}, topping{e} {}
};

class Customer
{
public:
    string firstname;
    string lastname;
    int customerid;
    vector<Customer> customers;
    void addcustomer();
    Customer(int a, string b, string c)
        : customerid{a}, firstname{b}, lastname{c} {}
};

class Order
{
public:
    int orderedpizzaid;
    int orderingcustomerid;
    int orderid;
    vector<Order> orders;
    void neworder();
    void data();
    Order (int a, int b, int c) 
    : orderid{a}, orderingcustomerid{b}, orderedpizzaid{c} {}
};

//I added in these placeholder objects so that I could run functions/push back vectors that belong to these functions' classes. I'm not sure whether there is a more sophisticated way to do this.
//I used negative integers just in case positive ones would interfere with actual pizza/customer IDs.
Pizza x{-1, " ", " ", " ", " "};
Customer y{-1, " ", " "};
Order z{-1, -1, -1};

void Pizza::addtomenu()
{
    cout << "Please enter the crust, sauce, cheese, and topping that this pizza will have, all separated by spaces.\n";
    cin >> crust >> sauce >> cheese >> topping;
    pizzaid = pizzas.size();
    x.pizzas.push_back(Pizza{pizzaid, crust, sauce, cheese, topping});
    cout << "The pizza has been added.\n";
}

void Customer::addcustomer()
{
    cout << "Please enter the first and last name of the customer, separated by spaces.\n";
    cin >> firstname >> lastname;
    customerid = customers.size();
    y.customers.push_back(Customer{customerid, firstname, lastname});
    cout << "The customer has been added.\n";
}

void Order::neworder()
{
    int orderid;
    int orderedpizzaid;
    int orderingcustomerid;
    bool trueflag1 = 0;
    bool trueflag2 = 0;
    string entry;
    cout << "Please enter the customer's ID, followed by the ID of the pizza being ordered. Separate the two with spaces.\n";
    if (cin >> orderingcustomerid >> orderedpizzaid)
    {
        for (int d = 0; d < y.customers.size(); d++)
        {
            if (orderingcustomerid == y.customers[d].customerid)
            {
                trueflag1 = 1;
                orderingcustomerid = d;
            }
        }

        if (trueflag1 == 0)
        {
            cin.clear();
            cin.ignore(1000, '\n');
            cout << "That ID does not match any customer in the system.\n";
            return;
        }

        for (int e = 0; e < x.pizzas.size(); e++)
        {
            if (orderedpizzaid == x.pizzas[e].pizzaid)
            {
                cin.clear();
                cin.ignore(1000, '\n');
                trueflag2 = 1;
                orderedpizzaid = e;
            }
        }

        if (trueflag2 == 0)
        {
            cout << "That ID does not match any pizza in the system.\n";
            return;
        }

        {
            cout << "The following customer: " << y.customers[orderingcustomerid].customerid << " " << y.customers[orderingcustomerid].firstname << " " << y.customers[orderingcustomerid].lastname << " ";
            cout << "will be ordering the following pizza: " << x.pizzas[orderedpizzaid].pizzaid << " " << x.pizzas[orderedpizzaid].crust << " " << x.pizzas[orderedpizzaid].sauce << " " << x.pizzas[orderedpizzaid].cheese << " " << x.pizzas[orderedpizzaid].topping << ".\n";
            cout << "Is that correct? If yes, press 1; if no, press 0.\n";
            cin >> entry;
            if (entry == "1")
            {orderid = orders.size();
            //The orders ID is pushed back with only the order ID and (copies of)
//the pizza and customer IDs. However, this information will be sufficient to 
//reproduce all of the customer and pizza information that corresponds to the 
//customer and pizza IDs, as shown in the data function. 
               z.orders.push_back(Order{orderid, orderingcustomerid, orderedpizzaid});
                cout << "The order has been placed.\n";
            }
            else
            {
                cout << "Order canceled.\n";
                return;
            }
        }
    }
    else
    {
        cin.clear();
        cin.ignore(10000, '\n');
        cout << "Please enter your input in integer form.\n";
    }
}

void Order::data()
{
    cout << "Pizzas entered into system so far:\n";
    for (int d = 0; d < x.pizzas.size(); d++)
    {
        cout << x.pizzas[d].pizzaid << " " << x.pizzas[d].crust << " " << x.pizzas[d].sauce << " " << x.pizzas[d].cheese << " " << x.pizzas[d].topping << "\n";
    }

    cout << "Customers entered into system so far:\n";
    for (int d = 0; d < y.customers.size(); d++)
    {
        cout << y.customers[d].customerid << " " << y.customers[d].firstname << " " << y.customers[d].lastname << "\n";
    }

cout << "Orders entered into system so far:\n";
for (int d = 0; d < z.orders.size(); d++)
    {
        //Each order is given an order ID that equals that order's position in the 
//orders vector. The orders vector stores both each order's ID and copies of the IDs
//of the pizza and customer that were included in that order.
        //Therefore, for each order in the orders vector, the following code: (1) prints
// the corresponding order id; (2) prints information from the customers vector for the 
//customer whose customerid matches the orders vector's orderingcustomerid; and (3) prints
// information from the pizzas vector for the pizza whose pizzaid matches the orders 
//vector's orderingpizzaid.
        cout << "Order ID: " << z.orders[d].orderid; 
        cout << " Customer information: " <<  y.customers[z.orders[d].orderingcustomerid].customerid << " " << y.customers[z.orders[d].orderingcustomerid].firstname << " " << y.customers[z.orders[d].orderingcustomerid].lastname;
        cout << " Pizza information: " << x.pizzas[z.orders[d].orderedpizzaid].pizzaid << " " << x.pizzas[z.orders[d].orderedpizzaid].crust << " " << x.pizzas[z.orders[d].orderedpizzaid].sauce << " " << x.pizzas[z.orders[d].orderedpizzaid].cheese << " " << x.pizzas[z.orders[d].orderedpizzaid].topping << "\n";
    }

}

int main()

{
    //These two push_back functions are added to create test items for debugging purposes.
    x.pizzas.push_back(Pizza{0, "wheat", "amatriciana", "provolone", "squid"});
    y.customers.push_back(Customer{0, "Bjarne", "Stroustrup"});

    string entry;
    while (true)
    {
        cout << "Welcome to the Pizza Orderer 5000. To enter a new customer, enter addcustomer. To enter a new pizza to the menu, enter addtomenu. To enter a new order, enter order. To list all data in the system, enter data. To quit, enter quit.\n";
        cin >> entry;
        if (entry == "addcustomer")
            y.addcustomer();
        else if (entry == "addtomenu")
            x.addtomenu();
        else if (entry == "order")
            z.neworder();
        else if (entry == "data")
            z.data();
        else if (entry == "quit")
            break;
        else
        {
            cin.clear();
            cin.ignore(10000, '\n');
            cout << "I'm sorry, that input was not recognized. Please try again.\n";
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-06-08
    • 2017-03-28
    • 2011-03-04
    • 2021-10-20
    • 1970-01-01
    • 2012-11-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多