无法分配给 const 成员函数中的非静态数据成员

新手上路,请多包涵

我正在尝试使用 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 。所以,我在 ChangeBalance 函数中添加了“const”。但是,在这样做之后,我在 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());
        }
    }
}

此外,我最初粘贴的代码来自一个更大的代码库,在发布问题之前我没有删除所有必要的命名空间内容。我为混乱道歉。

原文由 bpgeck 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 686
2 个回答

unordered_set 的成员是常量,默认情况下,一旦它们在 unordered_set 中就不能更改。您正在尝试更改集合中的对象,编译器正确地告诉您您不能这样做。

正确执行此操作的唯一可能方法(仅出于教育目的进行解释,因为这是糟糕的班级设计):

  1. 将可以以这种方式修改的各个字段显式声明为 mutable

  2. 对您的 unordered_set 使用自定义哈希函数,并且哈希函数必须从计算的哈希值中排除可变字段的值。

否则,修改集合中对象的内容显然会改变其哈希值,从而导致未定义的行为。

同样,这仅出于提供信息的目的进行解释。这不是一个好的类设计。

干净的方法是为每个 CreditCard 分配一个唯一标识符(你知道,就像信用卡号一样?),并使用普通的 std::map 来查找 CreditCard 按他们的编号。

原文由 Sam Varshavchik 发布,翻译遵循 CC BY-SA 3.0 许可协议

ChangeBalance 不适合拥有 const 语义。就其名称的本质而言,您正在修改对象。使函数非常量。

 void ChangeBalance(int amount) {
    balance += amount;
}

另一个问题是你没有正确调用你的函数。你应该这样做:

 iter->ChangeBalance(chargeAmount);

我会提到在某些情况下您想要修改 const 对象中的值,并且有一个 mutable 类型修饰符。但是, 不要 用它来解决您当前的错误!

原文由 paddy 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题