#c #design-patterns #encapsulation #unordered-map #unordered-set
Вопрос:
Я просматривал несколько руководств о том, как создать неупорядоченный набор для класса/структуры. Я нашел этот простой для понимания код (как разработчик Java), который делает свое дело:
#include <iostream>
#include <unordered_set>
using namespace std;
struct Node{
int val;
bool operator==(const Nodeamp; n) const{
return (this->val == n.val);
}
};
class HashFunction{
public:
size_t operator()(const Nodeamp; 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
класс a, сделать int val
закрытое поле a и добавить unordered_set<Node, HashFunction> neighbours
в качестве поля в Node
класс.
Если нет, то какова хорошая практика, чтобы классы/структуры были хорошо инкапсулированы и имели наборы/поля карт для классов?
Комментарии:
1. Обратите внимание, что
Node
в C означает фактический объект, а не указатель, как в Java. Коллекция «соседей» нуждается во взаимосвязи «многие ко многим», которая может быть реализована только с помощью указателей.2. Структура-это просто класс, по умолчанию открытый для всех участников. Если вы сделали val закрытым, то хэш класса не сможет его вернуть.
3. @BenVoigt спасибо за комментарий, вы имеете в виду, что набор «соседей» должен иметь узел* в качестве шаблона?
4. @sucksatnetworking спасибо за комментарий. Теперь я попытаюсь сделать «Узел» классом.
Ответ №1:
Здесь есть несколько вопросов, поэтому я постараюсь ответить на них по порядку:
может сделать
struct Node
класс а
Да, struct
и class
отличаются только разрешениями по умолчанию (в struct
том, что есть public
, если не указано иное, в class
том, что они есть private
). Итак, это код, идентичный тому, что вы написали:
class Node{
public:
int val;
bool operator==(const Nodeamp; n) const{
return (this->val == n.val);
}
};
сделайте поле
int val
закрытым и добавьтеunordered_set<Node, HashFunction> neighbours
в качестве поля вNode
класс
Да, ты можешь. Самый простой способ, который я могу придумать, чтобы сделать этот переход из кода, который вы написали,-это сделать HashFunction
его подклассом Node
. Например:
class Node {
class HashFunction {
public:
size_t operator()(const Nodeamp; n) const{
return n.val;
}
};
public:
Node(int _val) : val(_val) {}
bool operator==(const Nodeamp; n) const{
return (this->val == n.val);
}
// More methods here
private:
int val;
unordered_set<Node, HashFunction> neighbours;
};
Если нет, то какова хорошая практика, чтобы классы/структуры были хорошо инкапсулированы и имели наборы/поля карт для классов?
Я предполагаю, что в данном случае это несколько немой вопрос, но общий ответ заключается в том, чтобы предоставить только минимально необходимый интерфейс. Например, прямо сейчас HushFunction
осознает внутреннее содержание Node
. чтобы увеличить инкапсуляцию, мы могли бы добавить hush
метод Node
и HushFunction
вызвать этот метод. Таким образом, если содержание Node
меняется, ничто за пределами Node
не должно об этом знать.