如何在 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
是的,struct
和 class
只是默认权限不同(在 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
之外的任何人都不需要知道它。
我在看一些关于如何为 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
是的,struct
和 class
只是默认权限不同(在 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 addunordered_set<Node, HashFunction> neighbours
as a field to theNode
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
之外的任何人都不需要知道它。