我正在尝试使用 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());
}
}
}
此外,我最初粘贴的代码来自一个更大的代码库,在发布问题之前我没有删除所有必要的命名空间内容。对于造成的困惑,我深表歉意。
最佳答案
默认情况下,unordered_set
的成员是常量,一旦进入 unordered_set
就无法更改。您正在尝试更改集合中的对象,而编译器正确地告诉您您不能这样做。
正确执行此操作的唯一可能方法(仅出于教育目的进行解释,因为这是糟糕的类设计):
将可以通过这种方式修改的各个字段显式声明为
mutable
。在您的
unordered_set
中使用自定义哈希函数,并且哈希函数必须从计算的哈希值中排除可变字段的值。
否则,修改集合中对象的内容,显然会改变其哈希值,这将导致未定义的行为。
再次说明,这仅供引用。这不是一个好的类设计。
做到这一点的简洁方法是为每个 CreditCard
分配一个唯一标识符(你知道,就像信用卡号一样?),并使用普通的 std::map
,通过号码查找 CreditCard
。
关于c++ - 无法分配给 const 成员函数中的非静态数据成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39886349/