我被要求建立以下内容。在这个阶段,我只能编写相应的.h文件的任务,不幸的是,尽管经过数小时的研究,并且由于成为远程教育学生的困境,我的老师不给我帮助。我不确定这些.h结构是否正确,我不确定从哪里开始创建函数。你能告诉我我的.h文件是否正确你能告诉我如何创建这个.h文件相应的功能吗?
包含三个成员的Customer结构(在头文件Customer.h中定义): 客户名称,用户ID和PIN。
#ifndef CUSTOMER_H
#define CUSTOMER_H
using namespace std;
struct customer
{
std::string name;
std::string pin;
std::string user_id
};
创建客户的函数CreateCustomer()
。它有三个参数来初始化结构的每个成员(客户名称,用户ID和PinNumber)。所有参数都应具有默认参数空白值。原型:
Customer * CreateCustomer(const string& name,const string& id,const string& pin)
Customer * CreateCustomer(const string& name,const string& id,const string& pin){ 返回新客户{name,id,pin};
包含三个成员的事务结构(在头文件Transaction.h中定义):Transaction Date,Description和Amount。金额不能为负值。
// .h文件
struct Transaction { std::string date; std::string description; double amount; };
创建Transaction的函数CreateTransaction()。它有三个参数来初始化结构的每个成员(交易日期,描述和金额)。所有参数都应具有默认参数值。日期设置为“01/01/2014”,描述为空白,金额为零。原型: Transaction * CreateTransaction(const string& date,const string& description,const double& amount))
transaction* CreateTransaction(const string& date, const string& description, const double& amount) {return new transaction { date, description, amount};
包含七个成员的帐户结构(在头文件Account.h中定义): 帐户持有人,数量,余额,总存款,提款总额,交易清单数组 现有交易记录中最多100条记录和交易计数。
// the .h file struct Account { Customer customer; int number; double balance, total_deposit, total_withdrawal}
创建帐户的函数CreateAccount()。它有六个参数来初始化结构的每个适当的成员。 date参数用于为Transaction List数组创建第一个事务,描述是来自balance参数的Opening balance。因此,在创建帐户后,应将事务计数设置为1。来自第三个参数的所有参数都应具有默认参数值。日期设置为“01/01/2014”,余额,存款和取款设置为零值。原型:
帐户* CreateAccount(const Customer& customer,const std :: string& openingDate =“01/01/2014”,const double& openingBalance = 0,const 双&安培;存款= 0,const double&撤回= 0);
考虑到上述情况我已经获得了一个数据集,其想法是它曾经有一个特定的输出,他们的代码提供了我的作业表粘贴在下面
> Provided Code - main() int main() { Customer* Mary =
> CreateCustomer("Mary Jones", "235718", "5074"); Customer* John =
> CreateCustomer("John Smith", "375864", "3251"); Account* MaryAccount =
> CreateAccount(*Mary, "06-3121-10212357", "01/03/2014", 100); Account*
> JohnAccount = CreateAccount(*John, "06-3121-10213758", "10/03/2014");
> RecordWithdraw(MaryAccount, CreateTransaction("01/03/2014", "ATM
> Withdrawal", 50) ); RecordDeposit(MaryAccount,
> CreateTransaction("02/03/2014", "Deposit", 90) );
> RecordWithdraw(MaryAccount, CreateTransaction("04/03/2014", "ATM
> Withdrawal", 150) ); RecordDeposit(MaryAccount,
> CreateTransaction("05/03/2014", "Deposit", 20) );
> RecordWithdraw(MaryAccount, CreateTransaction("05/03/2014",
> "Withdraw", 100) ); RecordWithdraw(MaryAccount,
> CreateTransaction("05/03/2014", "Withdraw", 50) );
> RecordDeposit(JohnAccount, CreateTransaction("11/03/2014", "Deposit",
> 20) ); RecordDeposit(JohnAccount, CreateTransaction("12/03/2014",
> "Deposit", 80) ); RecordWithdraw(JohnAccount,
> CreateTransaction("12/03/2014", "Withdraw", 50) );
> PrintReport(MaryAccount); PrintReport(JohnAccount); return 0; }
答案 0 :(得分:2)
如果我以前的评论冒犯了你,我很抱歉。我想要推荐的是学习你可能在课堂上遗漏的语言的基础知识。
我将在这里总结一下要点,让你重温记忆:
他们的目的是阻止程序包含多个定义。他们的通用语法如下:
#ifndef X
#define X
...
#endif
这样做是为了在首次包含文件时,ifndef X
将“评估”到预处理器中的true
,并输入ifndef
的正文(正文结束) #endif
结束的地方)。正文应该做的第一件事是定义X
,以便下次包含文件时,ifndef
将“评估”到预处理器中的false
,并将“跳过”包含的定义在体内。
标识符X
当然应该对每个文件都是唯一的。
using namespace
指令如果包含<string>
(请注意标题不应包含.h
),则应包含string
命名空间中定义的std
类。现在你有两个选择:
std::string
std
导入using namespace std;
命名空间,并能够使用string
这首先被认为是更好的,但在学术环境中,第二个主要是使用。只需选择一种方法并坚持下去。
std Transaction[]
没有任何意义。每个声明/声明都应以分号(;
)结尾,并且您已在程序的其他部分中执行此操作。
您的客户结构应包含:
名称可以用字符串表示,因此我会使用std::string
。使用的ID和引脚看起来像数字值,因此我可能会使用int
两者,导致结构为:
struct Customer
{
std::string name;
int pin;
int user_id;
};
CreateCustomer
这是分配:
创建Customer的函数CreateCustomer()。它有三个参数来初始化结构的每个成员(Customer Name,User ID和PinNumber)。所有参数都应具有默认参数空白值。
原型:
Customer* CreateCustomer(const string& name, const string& id, const string& pin)
从回归类型来看,我实际上害怕作业要求你做什么。他可能会要求你返回一个动态分配的对象,这是非常糟糕的做法。但只是为了分配,这很简单,您可以这样做:
Customer* CreateCustomer(const string& name, const string& id, const string& pin) {
return new Customer { name, id, pin };
}
没有太多可以解释的。这是动态分配的内存,你应该记得以后再delete
。 “动态记忆”的主题肯定太长了,不能在这里解释清楚,只需阅读你解释它的书的章节。
Transaction
结构你为这个绘制的草图实际上非常准确。描述和日期均为std::string
,金额为double
。唯一的问题是你不应该担心在名称前加Transaction
前缀,因为它们是Transaction
结构的本地代码:
struct Transaction {
std::string date;
std::string description;
double amount;
};
CreateTransaction
函数这与之前的CreateCustomer
函数完全相同。既然我们有Transaction
这应该是微不足道的。我会将此作为练习留给读者。
Account
作业要求:
对于帐户持有人,我们提供了全新的Customer
课程。对于该号码,我们可以再次使用int
。对于balance
,total_deposit
和total_withdrawal
,我们可以使用double
(处理资金时,需要浮点数来表示分数)。
所以struct
应该是这样的:
struct Account {
Customer customer;
int number;
double balance, total_deposit, total_withdrawal;
现在对于阵列来说这会让人感到困惑。一方面看起来你的教授希望你使用一个C数组,另一方面(事务计数)似乎你应该更有活力。在我看来,您应该包含<vector>
并使用std::vector
。如果您还没有谈过矢量,可以使用数组:
Transaction transactions[100];
};
CreateAccount
这里的任务非常令人困惑,至少在我看来并且显然没有原型,但我确信你可以通过修改来解决问题:
for
循环new
答案 1 :(得分:0)
根据@Jefffrey的回答,这里有一些我在你的程序中注意到的事情。
struct CUSTOMER_H
{
std::string name[8];
std::string pin;
std::string Userid;
};
看起来你对基于字符的字符串和std::string
之间的区别感到困惑。使用C样式的基于字符的字符串,可以创建char
的数组。数组必须是固定大小的,你必须留下尾随空的最后一个元素\0
,它标记字符串的结尾。所以在这种情况下,你可以这样做:
char name[8]; //this creates a character array with 8 elements numbered 0-7. You need to leave name[7] alone so it can hold the trailing \0, though, or you'll crash your program. So this can effectively hold a 7-character name.
但是,由于你在其他地方使用std::string
,你可能也想在这里做。与基于字符的字符串不同,std::string
是一个可变长度的字符串,它负责标记自己的结尾。你不需要在这里创建一个数组;刚
std::string name;
会做的。
包含三个成员的Transaction结构(在头文件Transaction.h中定义):Transaction Date,Description和Amount。金额不能为负值。
听起来,交易结构比数据容器更复杂:如果您确保数量永远不会消极,那么您需要使用 getters < / em>和 setters 。这些是简单的功能,旨在提供对分配给变量的内容的一些控制。他们的工作方式如下:
//Transaction.h: we're just declaring things here
struct Transaction
{
//<snip>
double getAmount();
void setAmount(double newAmount);
private:
double amount;
}
顾名思义,getAmount
函数将返回amount
中存储的值。 setAmount
函数应检查以确保newAmount
为正数,并且仅在amount
为正数时才存储。private
另外值得注意的是amount
关键字:如果使用交易的任何人都可以直接查看和更改private
变量,那么我们的特殊getter和setter对我们没有太大作用,因此amount
让我们将它隐藏在Transaction类之外的任何东西中。这样,只有Transaction类中的代码才能更改//Transaction.cpp: we're actually implementing things here. Yey code!
double Transaction::getAmount() //note that we prefix the method name with the class name and a double colon. This is required when you're creating a class method.
{
return amount; //short and sweet. We don't need to do anything special here, we're just letting outside code see the value of amount since they can't access it directly.
}
void Transaction::setAmount(double newAmount)
{
if (newAmount > 0) //this is why we're doing the whole getter-setter thing. Now we get to control what goes into amount: amount will only be updated if newAmount > 0.
{
amount = newAmount;
}
}
。
我怀疑你以前见过这些,所以我会为你写这些:
std::vector
包含七个成员的帐户结构(在头文件Account.h中定义):帐户持有人,数量,余额,总存款,总提款,最多100个记录的交易清单数组以及现有交易记录的交易计数。 / p>
@ Jefffrey在这里的答案非常好,所以你应该大部分都遵循它。我只想注意一件小事:交易清单/交易计数。 (好吧,两件小事。)
根据我在介绍级别课程中看到的内容,我还是愿意打赌你还没有覆盖struct Account
{
//<snip>
Transaction transactions[100];
int transactionCount;
}
,固定大小的数组要求支持这个理念。你的教授可能正在寻找的是一个C风格的交易数组,它有一个单独的交易计数器变量:
transactions
同样,请务必记住,transactionCount
数组是通过索引0-99,不 1-100访问的。因此,如果transactions[1]
为2,并不意味着,您可以访问transactions[2]
和transactions[0]
。您的代码将执行您不会感激的事情,包括返回垃圾值到可能崩溃。您想要transactions[1]
和std::int
。另外,请勿使用int
;只需将整数变量声明为//CreateAccount prototype:
Account* CreateAccount(const Customer& customer, const std::string& openingDate = "01/01/2014", const double& openingBalance = 0, const double& deposit = 0, const double& withdraw = 0);
。
创建帐户的函数CreateAccount()。它有六个参数来初始化结构的每个适当的成员。 date参数用于为Transaction List数组创建第一个事务,描述是来自balance参数的Opening balance。因此,在创建帐户后,应将事务计数设置为1。来自第三个参数的所有参数都应具有默认参数值。日期设置为&#34; 01/01 / 2014&#34;,余额,存款和取款设置为零值。
这很令人困惑,但让我们试着将其分解。
的createAccount:
由于缺乏信息,此代码可能不完整或有些错误,但我会尽我所能处理您提供的内容。
Account*
首先,缺少一个参数。我不知道它是什么,所以我无法添加它;你需要这样做。
另请注意,我们正在返回Account
- 指向帐户的指针。这是非常糟糕的主意,通常您只想返回= <value>
- 这是一个普通的帐户对象,不会因为手动内存分配/释放而导致您头痛。不幸的是,这位教授似乎喜欢返回动态创建的对象,所以我们需要按照他的方式去做。 请在没有充分理由的情况下,不要在实际代码中执行此操作。
最后,请注意= 0
(= "01/01/2014"
,CreateAccount
) - 这是指定默认参数值的方式。调用CreateAccount
的人将能够跳过这些参数,并且将使用我们在原型中指定的参数。或者他们可以调用//for the purposes of the next few lines of code, JoeCool is a valid Customer object that we've already set up using CreateCustomer.
CreateAccount(JoeCool); //creates an account belonging to JoeCool. The opening date will be automatically set to 01/01/2014 and the balance, deposit and withdrawal will all be set to 0.
CreateAccount(JoeCool, "09/10/14"); //creates an account belonging to JoeCool. The opening date will be set to 09/10/14, overriding our default date; however, since we didn't specify a balance, deposit, or withdrawal, they'll all be set to 0.
CreateAccount(JoeCool, "12/11/15", 50, 100, 25); //creates an account belonging to JoeCool. We've overridden all our default parameters, so the opening date will be set to 12/11/15, the opening balance will be set to 50, the deposit will be set to 100, and the withdrawal will be set to 25.
并指定所有参数,我们的默认值将被覆盖。所以这三个调用都是有效的:
CreateAccount
我实际上会将此作为练习实施。但是,我认为您在执行此操作时需要记住一些一般概念。
CreateTransaction
中做所有事情;将部分工作交给getTransactionCount
。getTransaction(int index)
(没有setter for this!事务计数将在内部递增,不需要任何外部代码来设置它),CreateTransaction
,当然还有CreateTransaction
。这样,getTransaction
可以创建一个新的事务并增加事务计数器,getTransactionCount
可以返回一个单独的事务项,而不是让外部代码访问您的完整事务数组,CreateTransaction
可以使确保外部代码不会弄乱你的交易柜台。CreateTransaction
的原因:你可以在一个地方编写健全性检查,然后让其余的代码使用它们,而不是必须检查一切到处。只需进行多笔交易来设置余额,然后存入任何东西,然后提取任何东西,让{{1}}决定主叫代码是否做了非法行为(负存款,负余额,提取大于余额)。