如何在 C++ 中使用 unordered_set/map 时封装良好的 类?

How to make well-encapsulated classes while using unordered_set/map in c++?

我在看一些关于如何为 class/struct 制作 unordered_set 的教程。我发现这个易于理解的代码(作为 Java 开发人员)可以解决问题:

#include <iostream>
#include <unordered_set>
using namespace std;

struct Node{
    int val;
  
    bool operator==(const Node& n) const{
        return (this->val == n.val);
    }
};

class HashFunction{
    public:
        size_t operator()(const Node& n) const{
            return n.val;
        }
};

int main(){
    Node n1 = { 1 }, n2 = { 2 },
         n3 = { 3 }, n4 = { 4 };

    unordered_set<Node, HashFunction> us;
    us.insert(n1);
    us.insert(n2);
    us.insert(n3);
    us.insert(n4);
    
    for (auto node : us){
        cout << node.val << " ";
    }
    cout << endl;
    return 0;
}

我想知道我们是否可以将 struct Node 设为 class,将 int val 设为私有字段并将 unordered_set<Node, HashFunction> neighbours 作为字段添加到 [=16] =] class.

如果不是,保持 classes/structs 良好封装并为 class 提供 sets/maps 字段的良好做法是什么?

这里有几个问题,我尽量按顺序回答:

can make the struct Node a class

是的,structclass 只是默认权限不同(在 struct 中是 public,除非另有说明,在 class 中是private) 所以这与您编写的代码相同:

class Node{
public:
    int val;
  
    bool operator==(const Node& n) const{
        return (this->val == n.val);
    }
};

make the int val a private field and add unordered_set<Node, HashFunction> neighbours as a field to the Node class

是的,你可以。我能想到的从您编写的代码进行转换的最简单方法是使 HashFunction 成为 Node 的子 class。 例如:

class Node {
    class HashFunction {
        public:
            size_t operator()(const Node& n) const{
                return n.val;
            }
    };

public:
    Node(int _val) : val(_val) {}

    bool operator==(const Node& n) const{
        return (this->val == n.val);
    }

    // More methods here

private:
    int val;
    unordered_set<Node, HashFunction> neighbours;
};

If not, what is a good practice to keep classes/structs well-encapsulated and have sets/maps fields for classes?

我想在这种情况下这是一个有点无声的问题 - 但一般的答案是仅公开所需的最低接口。例如,现在 HushFunction 知道 Node 的内部内容。为了增加封装,我们可以向 Node 添加一个 hush 方法并让 HushFunction 调用该方法。这样,如果 Node 的内容发生变化,Node 之外的任何人都不需要知道它。