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