我正在尝试使用std::unordered_set
作为哈希表来存储许多CreditCard
。 CreditCard
和另一个类CardDatabase
的定义如下:
class CreditCard {
private:
string cardHolder;
unsigned long long cardNumber;
int limit;
int balance;
public:
CreditCard(string in_cardHolder, string in_cardNumber, int in_limit) {
cardHolder = in_cardHolder;
cardNumber = stoll(in_cardNumber);
limit = in_limit;
balance = 0;
}
void ChangeBalance(int amount) const {
balance += amount; // SECOND ERROR
}
};
class CardDatabase {
private:
unordered_set<CreditCard> cards;
unordered_set<CreditCard>::iterator iter;
public:
CardDatabase() { }
void AddCard(cardHolder, cardNumber, int limit) {
CreditCard tempCard = CreditCard(cardHolder, cardNumber, limit);
cards.insert(tempCard);
}
void Charge(string cardHolder, int chargeAmount) {
iter = cards.find(cardHolder);
iter->ChangeBalance(chargeAmount); // FIRST ERROR
}
}
最初我在FIRST ERROR
:Member function 'ChangeBalance' not viable: 'this' argument has type 'const CreditCard', but function is not marked const
收到以下编译错误。所以,我将“const”添加到ChangeBalance
函数中。但是,在执行此操作后,我在SECOND ERROR
:Cannot assign to non-static member within const member function 'ChangeBalance'
获得了以下编译错误。
有没有办法在不将balance
更改为静态变量的情况下修复此错误?显然,每个CreditCard
实例的余额都不同。
感谢任何帮助。
谢谢大家的快速解答。我觉得我应该澄清一些事情。我已在代码的其他地方添加了正确的哈希功能:
namespace std {
template <>
struct hash<CreditCard> {
size_t operator()(const CreditCard& cc) const
{
return hash<string>()(cc.GetCardHolder());
}
}
}
另外,我最初粘贴的代码来自更大的代码库,在发布问题之前我没有删除所有必要的命名空间。我为这种困惑道歉。
答案 0 :(得分:4)
unordered_set
的成员是固定的,默认情况下,一旦他们在unordered_set
中就无法更改。您正在尝试更改集合中的对象,编译器正在告诉您不能执行此操作。
正确执行此操作的唯一可行方法(仅出于教育目的而解释,因为这是糟糕的课程设计):
明确声明可以这种方式修改为mutable
的各个字段。
对unordered_set
使用自定义哈希函数,哈希函数必须从计算哈希的值中排除可变字段的值。
否则,修改集合中对象的内容会明显改变其哈希值,这将导致未定义的行为。
同样,这仅用于提供信息。这不是一个好的课堂设计。
执行此操作的干净方法是为每个CreditCard
分配一个唯一标识符(您知道,就像信用卡号码?),并使用普通std::map
查找{{ 1}} s的数量。
答案 1 :(得分:2)
ChangeBalance
不适合 const 语义。根据它名称的本质,你正在修改对象。使函数非常量。
void ChangeBalance(int amount) {
balance += amount;
}
另一个问题是你没有正确调用你的功能。你应该这样做:
iter->ChangeBalance(chargeAmount);
我会提到有些情况下你想修改 const 对象中的值,并且有一个mutable
类型修饰符。但不使用它来解决当前的错误!
答案 2 :(得分:1)
void ChangeBalance(int amount)
不应该是const
- 它正在更改对象。
问题出现在迭代器中:cards.find
返回一个const
对象,因此不允许更改它。
解决这个问题的一种方法是让你的cards
设置一组指向卡片的指针,而不是卡片;或者用另一种方法找到匹配的卡
答案 3 :(得分:0)
在该代码中使用C ++语法快速松散,Hoss。很多错误都在拐角处等待
第一个错误:
iter->CreditCard::ChangeBalance(chargeAmount);
应该是
iter->ChangeBalance(chargeAmount);
由于unordered_set
不知道如何散列CreditCard
导致的错误,可能导致错误的语法错误。读一下:How do I use unordered_set?那就是说,unordered_set
可能不是这项工作的正确解决方案。 std::map<std::string, CreditCard>
看起来更有意义。
使用错误的解决方案解决上述问题导致
第二个错误:
void ChangeBalance(int amount) const
方法上的 const
表示该方法无法更改对象的状态。 in ChangeBalance
balance += amount;
尝试通过更新成员变量来更改对象的状态。
此外,编译器将在此处讨厌CreditCard::
:
CreditCard::CreditCard(string in_cardHolder, string in_cardNumber, int in_limit) {
cardHolder = in_cardHolder;
cardNumber = stoll(in_cardNumber);
limit = in_limit;
balance = 0;
}