c++ - 如何将 2 个类分成单独的 .h 文件并正确设置它们
问题描述
该代码在没有两个类的单独文件的情况下在 main 中运行良好,但是当我尝试将它们分开时,我得到很多错误说‘ItemToPurchase’ was not declared in this scope
。我假设它是因为我ItemToPurchase
在课堂上使用类,ShoppingCart
但我无法让它识别实现的位置
我在文件中尝试了这样的东西(如下),ShoppingCart.h
但它没有效果,我不确定我是否遗漏了其他东西做错了。
#ifndef ShoppingCart_h
#define ShoppingCart_h
#ifndef ItemToPurchase_h
#define ItemToPurchase_h
我在下面发布了工作代码
我不确定如何为 5 个文件main
和 4 个.h
文件设置文件头
如果有人可以展示如何设置标题,那将是理想的,我是一名学生,此时有点迷茫
#include <iostream>
#include <vector>
#include <string>
using namespace std;
class ItemToPurchase
{
private:
string itemName;
int itemPrice;
int itemQuantity;
string itemDescription;
public:
ItemToPurchase()
{
itemName = "";
itemPrice = 0;
itemQuantity = 0;
itemDescription = "none";
}
ItemToPurchase(string name, string description, int price, int quantity)
{
itemName = name;
itemDescription = description;
itemPrice = price;
itemQuantity = quantity;
}
void SetName(string name)
{
itemName = name;
}
void SetPrice(int price)
{
itemPrice = price;
}
void SetQuantity(int quantity)
{
itemQuantity = quantity;
}
string GetName()
{
return itemName;
}
int GetPrice()
{
return itemPrice;
}
int GetQuantity()
{
return itemQuantity;
}
void SetDescription(string description)
{
itemDescription = description;
}
string GetDescription()
{
return itemDescription;
}
void PrintItemCost()
{
cout << itemName << " " << itemQuantity << " @ $" << itemPrice << " = $" << itemQuantity * itemPrice << endl;
}
void PrintItemDescription()
{
cout << itemName << ": " << itemDescription << endl;
}
};
//---------------------------------------------------------------
class ShoppingCart
{
private:
string customerName;
string currentDate;
vector <ItemToPurchase> cartItems;
public:
ShoppingCart()
{
customerName = "none";
currentDate = "January 1, 2016";
}
ShoppingCart(string name, string date)
{
customerName = name;
currentDate = date;
}
string GetCustomerName()
{
return customerName;
}
string GetDate()
{
return currentDate;
}
void AddItem(ItemToPurchase newItem)
{
cartItems.push_back(newItem);
}
void RemoveItem(string name)
{
bool temp = true;
for (int i = 0; i < cartItems.size(); i++)
{
if (name == cartItems[i].GetName())
{
cartItems.erase(cartItems.begin() + i);
temp = false;
}
}
if (temp == true)
{
cout << "Item not found in cart. Nothing removed." << endl << endl;
}
else
{
cout << endl;
}
}
void ModifyItem(int quantity, string name)
{
bool temp = true;
for (int i = 0; i < cartItems.size(); i++)
{
if (name == cartItems[i].GetName())
{
cartItems[i].SetQuantity(quantity);
temp = false;
}
}
if (temp == true)
{
cout << "Item not found in cart. Nothing modified." << endl << endl;
}
else
{
cout << endl;
}
}
int GetNumItemsInCart()
{
int total = 0;
for (int i = 0; i < cartItems.size(); i++)
{
total += cartItems[i].GetQuantity();
}
return total;
}
int GetCostOfCart()
{
int total = 0;
for (int i = 0; i < cartItems.size(); i++)
{
total += cartItems[i].GetPrice() * cartItems[i].GetQuantity();
}
return total;
}
void PrintTotal()
{
if (cartItems.size() == 0)
{
cout << GetCustomerName() << "'s Shopping Cart - " << GetDate() << endl;
cout << "Number of Items: 0" << endl << endl;
cout << "SHOPPING CART IS EMPTY" << endl << endl;
cout << "Total: $0" << endl << endl;
}
else
{
cout << customerName << "'s Shopping Cart - " << currentDate << endl;
cout << "Number of Items: " << GetNumItemsInCart() << endl << endl;
for (int i = 0; i < cartItems.size(); i++)
{
cartItems[i].PrintItemCost();
}
cout << endl << "Total: $" << GetCostOfCart() << endl << endl;
}
}
void PrintDescriptions()
{
cout << "Item Descriptions" << endl;
for (int i = 0; i < cartItems.size(); i++)
{
cartItems[i].PrintItemDescription();
}
cout << endl;
}
};
int main()
{
cout << "Enter customer's name:" << endl;
string name;
getline(cin, name);
cout << "Enter today's date:" << endl << endl;
string date;
getline(cin, date);
cout << "Customer name: " << name << endl;
cout << "Today's date: " << date << endl << endl;
ShoppingCart customer(name, date);
bool on = true;
bool check = true;
string select;
while (on)
{
cout << "MENU" << endl;
cout << "a - Add item to cart" << endl;
cout << "d - Remove item from cart" << endl;
cout << "c - Change item quantity" << endl;
cout << "i - Output items' descriptions" << endl;
cout << "o - Output shopping cart" << endl;
cout << "q - Quit" << endl << endl;
cout << "Choose an option:" << endl;
cin >> select;
while (check)
{
if (select == "a" || select == "d" || select == "c" || select == "i" || select == "o" || select == "q")
{
check = false;
}
else
{
cout << "Choose an option:" << endl;
cin >> select;
}
}
check = true;
if (select == "a")
{
cout << "ADD ITEM TO CART" << endl;
cout << "Enter the item name:" << endl;
cin.ignore();
string name;
getline(cin, name);
cout << "Enter the item description:" << endl;
string description;
getline(cin, description);
cout << "Enter the item price:" << endl;
int price;
cin >> price;
cout << "Enter the item quantity:" << endl << endl;
int quantity;
cin >> quantity;
ItemToPurchase temp(name, description, price, quantity);
customer.AddItem(temp);
}
else if (select == "d")
{
cout << "REMOVE ITEM FROM CART" << endl;
cout << "Enter name of item to remove:" << endl;
cin.ignore();
string name;
getline(cin, name);
customer.RemoveItem(name);
}
else if (select == "c")
{
cout << "CHANGE ITEM QUANTITY" << endl;
cout << "Enter the item name:" << endl;
cin.ignore();
string name;
getline(cin, name);
cout << "Enter the new quantity:" << endl;
int quantity;
cin >> quantity;
customer.ModifyItem(quantity, name);
}
else if (select == "i")
{
cout << "OUTPUT ITEMS' DESCRIPTIONS" << endl;
cout << customer.GetCustomerName() << "'s Shopping Cart - " << customer.GetDate() << endl << endl;
customer.PrintDescriptions();
}
else if (select == "o")
{
cout << "OUTPUT SHOPPING CART" << endl;
customer.PrintTotal();
}
else if (select == "q")
{
on = false;
}
}
}
解决方案
这实际上是从底部开始,然后逐步解决问题。首先,使用标题通常会有标题保护,有些人使用#pragma 一旦有人使用#ifndef/#define/#endif。我个人更喜欢后者,但在以#pragma once为标准的地方工作。所以你通常会遵循你在哪里工作或你被告知的标准。
下一点帮助是使用:
using namespace std;
我个人不喜欢它,因为你最终会污染命名空间,但同样,它是关于标准和遵循编码实践的。这通常只是避免在类名之前键入太多std::范围的一种方法。
话虽如此,让我们进入代码......在底部你有ItemToPurchase这不包括除了标准 C++ 的其他类,所以你最终得到:
// ItemToPurchase.h
#pragma once
#include <iostream>
#include <vector>
#include <string>
using namespace std;
class ItemToPurchase
{
private:
string itemName;
int itemPrice;
int itemQuantity;
string itemDescription;
public:
ItemToPurchase()
{
itemName = "";
itemPrice = 0;
itemQuantity = 0;
itemDescription = "none";
}
ItemToPurchase(string name, string description, int price, int quantity)
{
itemName = name;
itemDescription = description;
itemPrice = price;
itemQuantity = quantity;
}
void SetName(string name) { itemName = name; }
void SetPrice(int price) { itemPrice = price; }
void SetQuantity(int quantity) { itemQuantity = quantity; }
string GetName() { return itemName; }
int GetPrice() { return itemPrice; }
int GetQuantity() { return itemQuantity; }
void SetDescription(string description) { itemDescription = description; }
string GetDescription() { return itemDescription; }
void PrintItemCost() {
cout << itemName << " " << itemQuantity << " @ $" << itemPrice << " = $" << itemQuantity * itemPrice << endl; }
void PrintItemDescription() { cout << itemName << ": " << itemDescription << endl; }
};
顺便说一句,您也许应该 const 限定 Get 方法。无论如何,上面的内容可以放入ItemToPurchase.h头文件,因为它包含它需要的所有内容。
接下来是ShoppingCart类。这专门命名了 ItemToPurchase,因此需要包含该标题。它还应该包括它使用的标准类型和类的标题。这通常是确保标头不完全依赖于另一个标头可能包含的标头的最佳方法。
// ShoppingCart.h
#pragma once
#include "ItemToPurchase.h"
#include <vector>
#include <iostream>
#include <string>
class ShoppingCart
{
private:
string customerName;
string currentDate;
vector <ItemToPurchase> cartItems;
public:
ShoppingCart()
{
customerName = "none";
currentDate = "January 1, 2016";
}
ShoppingCart(string name, string date)
{
customerName = name;
currentDate = date;
}
string GetCustomerName() { return customerName; }
string GetDate() { return currentDate; }
void AddItem(ItemToPurchase newItem) { cartItems.push_back(newItem); }
void RemoveItem(string name)
{
bool temp = true;
for (int i = 0; i < cartItems.size(); i++)
{
if (name == cartItems[i].GetName())
{
cartItems.erase(cartItems.begin() + i);
temp = false;
}
}
if (temp == true)
{
cout << "Item not found in cart. Nothing removed." << endl << endl;
}
else
{
cout << endl;
}
}
void ModifyItem(int quantity, string name)
{
bool temp = true;
for (int i = 0; i < cartItems.size(); i++)
{
if (name == cartItems[i].GetName())
{
cartItems[i].SetQuantity(quantity);
temp = false;
}
}
if (temp == true)
{
cout << "Item not found in cart. Nothing modified." << endl << endl;
}
else
{
cout << endl;
}
}
int GetNumItemsInCart()
{
int total = 0;
for (int i = 0; i < cartItems.size(); i++)
{
total += cartItems[i].GetQuantity();
}
return total;
}
int GetCostOfCart()
{
int total = 0;
for (int i = 0; i < cartItems.size(); i++)
{
total += cartItems[i].GetPrice() * cartItems[i].GetQuantity();
}
return total;
}
void PrintTotal()
{
if (cartItems.size() == 0)
{
cout << GetCustomerName() << "'s Shopping Cart - " << GetDate() << endl;
cout << "Number of Items: 0" << endl << endl;
cout << "SHOPPING CART IS EMPTY" << endl << endl;
cout << "Total: $0" << endl << endl;
}
else
{
cout << customerName << "'s Shopping Cart - " << currentDate << endl;
cout << "Number of Items: " << GetNumItemsInCart() << endl << endl;
for (int i = 0; i < cartItems.size(); i++)
{
cartItems[i].PrintItemCost();
}
cout << endl << "Total: $" << GetCostOfCart() << endl << endl;
}
}
void PrintDescriptions()
{
cout << "Item Descriptions" << endl;
for (int i = 0; i < cartItems.size(); i++)
{
cartItems[i].PrintItemDescription();
}
cout << endl;
}
};
现在我们完成了ShoppingCart.h和ItemToPurchase.h头文件,它们都受#pragma once保护。
最后,我们进入将包含在 .cpp 文件中的main函数。现在这个函数按名称命名了ItemToPurchase和ShoppingCart,所以它应该包含两个头文件。您可以只包含ShoppingCart.h,因为它包含ItemToPurcahse.h,但最好包含您命名的所有类型的标题。
最后,这给了你一个main.cpp文件,它应该是:
// main.cpp
#include "ItemToPurchase.h"
#include "ShoppingCart.h"
#include <iostream>
#include <string>
int main()
{
cout << "Enter customer's name:" << endl;
string name;
getline(cin, name);
cout << "Enter today's date:" << endl << endl;
string date;
getline(cin, date);
cout << "Customer name: " << name << endl;
cout << "Today's date: " << date << endl << endl;
ShoppingCart customer(name, date);
bool on = true;
bool check = true;
string select;
while (on)
{
cout << "MENU" << endl;
cout << "a - Add item to cart" << endl;
cout << "d - Remove item from cart" << endl;
cout << "c - Change item quantity" << endl;
cout << "i - Output items' descriptions" << endl;
cout << "o - Output shopping cart" << endl;
cout << "q - Quit" << endl << endl;
cout << "Choose an option:" << endl;
cin >> select;
while (check)
{
if (select == "a" || select == "d" || select == "c" || select == "i" || select == "o" || select == "q")
{
check = false;
}
else
{
cout << "Choose an option:" << endl;
cin >> select;
}
}
check = true;
if (select == "a")
{
cout << "ADD ITEM TO CART" << endl;
cout << "Enter the item name:" << endl;
cin.ignore();
string name;
getline(cin, name);
cout << "Enter the item description:" << endl;
string description;
getline(cin, description);
cout << "Enter the item price:" << endl;
int price;
cin >> price;
cout << "Enter the item quantity:" << endl << endl;
int quantity;
cin >> quantity;
ItemToPurchase temp(name, description, price, quantity);
customer.AddItem(temp);
}
else if (select == "d")
{
cout << "REMOVE ITEM FROM CART" << endl;
cout << "Enter name of item to remove:" << endl;
cin.ignore();
string name;
getline(cin, name);
customer.RemoveItem(name);
}
else if (select == "c")
{
cout << "CHANGE ITEM QUANTITY" << endl;
cout << "Enter the item name:" << endl;
cin.ignore();
string name;
getline(cin, name);
cout << "Enter the new quantity:" << endl;
int quantity;
cin >> quantity;
customer.ModifyItem(quantity, name);
}
else if (select == "i")
{
cout << "OUTPUT ITEMS' DESCRIPTIONS" << endl;
cout << customer.GetCustomerName() << "'s Shopping Cart - " << customer.GetDate() << endl << endl;
customer.PrintDescriptions();
}
else if (select == "o")
{
cout << "OUTPUT SHOPPING CART" << endl;
customer.PrintTotal();
}
else if (select == "q")
{
on = false;
}
}
}
这一切都应该起作用,您的类定义被分离到它们各自的 .h 文件中。
推荐阅读
- python - 如何将两个numpy数组合二为一?
- node.js - 包含 ProxyPass 和 ProxyPassReverse(AWS Lightsail 上的 Bitnami Node.js 服务器)的正确位置
- json - 读取真实数据库以快速重置密码
- javascript - .on('change') 有可靠的替代方案吗?
- python - 保护联系表单 API
- c++ - 如何定期同步线程?
- google-chrome - Chrome DevTools - 性能选项卡摘要
- javascript - mongoose switch 数据库进行具体操作
- javascript - 使用 puppeteer 在 iframe 中输入文本
- javascript - Webpack 加载字体图标但不加载字体本身