У меня есть вопрос, связанный с дизайном в C ++.
Я строю дерево для задания HW.Реализация дерева довольно проста.По сути это шаблонный класс
template <typename TYPE, typename KEY>
class Tree
{
public:
void Insert(TYPE& node);
void Remove(TYPE& node);
TYPE& Find (KEY key);
//etc.
};
Пока это просто фон.Теперь, позже, когда я использую Tree, у меня есть класс Employee, из которого я хочу иметь 2 дерева, но один раз использую ID в качестве ключа, а в другом - Salary в качестве ключа, но я не хочу дублировать данные.Очевидно, мне нужно реализовать 2 разных функции сравнения.Моей первой попыткой было сделать что-то вроде этого:
class Employee
{
public:
int ID;
float Salary;
};</p>
<p>enum COMPARE_RESULT
{
LESS_THAN = -1,
EVEN = 0,
GREATER_THAN = 1
}
template
class IComparable
{
public:
virtual COMPARE_RESULT Compare (const T& other) const = 0;
};</p>
<p>class EmployeeCompareByID : public Employee, public IComparable
{
public:
Compare (const T& other) const
{
//Compare IDs and return result
}
};</p>
<p>class EmployeeCompareBySalary : public Employee, public IComparable
{
public:
Compare (const T& other) const
{
//Compare Salaries and return result
}
};</p>
<p>typedef union
{
Employee employeeData;
EmployeeCompareByID employeeCompareByID;
EmployeeCompareBySalary employeeCompareBySalary;
}EmployeeUnion;</p>
<p>//finally the main would do something like this:
int main()
{
//first tree key is by ID
Tree empTreeByID;
//second tree key is by salary
Tree empTreeBySalary;</p>
<pre><code>EmployeeUnion emp;
emp.employeeData.ID = 1;
emp.employeeData.Salary = 1000.11;
empTreeByID.Insert(emp.employeeCompareByID);
empTreeBySalary.Insert(emp.employeeCompareBySlary);
//the same emp is referenced in both trees. Each by it's relevant member in union
}
, но этот подход не удался, потому что у моего класса Employee есть перегрузка конструктора, конструктора копирования и оператора, что определяет объединениена сотрудника невозможно.Кроме того, этот подход требует, чтобы реализация Tree выполняла static_cast для шаблона-аргумента TYPE для IComparable, что мне кажется правильным.
Другое возможное решение - передать указатель функции в конструктор Tree с указателемк соответствующей функции сравнения для этого экземпляра, но это кажется мне неуместным решением, и, возможно, довольно грязным и трудным для отладки позже.
Погугливая ограничения использования союзов с классами, я нашел пост, предлагающийрешить проблему, аналогичную моей, используя перегрузку оператора преобразования, но не сильно расширившись.
Я уверен, что это довольно распространенная проблема, которая имеет общее решение для проектирования, и я просто не знаю ее.
Любые мысли или комментарии приветствуются