Я считаю, что моя перегрузка оператора не работает для одного из моих двух типов данных. Моя программа работает с типом данных int, но не с моими определенными учениками классов. студенты - это дерево указателей, так что это может быть моей проблемой. Я обнаружил эту проблему, когда функция поиска не функционировала так, как планировалось. Я надеюсь получить совет относительно того, что я делаю неправильно с моими перегруженными операторами.
struct Students{
char lastName[20];
char firstName[20];
int IDnumber;
Students();
bool operator == (const Students);
bool operator > (const Students);
bool operator < (const Students);
friend ostream& operator << (ostream& stream, const Students* students);
};
template <class DataType>
TNode<DataType>* BST<DataType>::bstSearch(DataType search)
{
TNode<DataType>* y = root;
while (y!=NULL && search != y->data)
{
if (search < y->data)
{
y = y->left;
}
else
{
y = y->right;
}
}
return y;
}
вот мой код перегрузки
friend bool operator == (const Students& lh, const Students& rh);
friend bool operator > (const Students& lh, const Students& rh);
friend bool operator < (const Students& lh, const Students& rh);
bool operator ==(const Students& lh, const Students& rh)
{
return lh.IDnumber == rh.IDnumber;
}
bool operator > (const Students& lh, const Students& rh)
{
return lh.IDnumber > rh.IDnumber;
}
bool operator < (const Students& lh, const Students& rh)
{
return lh.IDnumber < rh.IDnumber;
}
это объекты дерева, которые я создаю
BST<Students*> stree;
BST<int> itree;
Если вы используете "Тип" Students*
для типа данных, то это:
if (search < y->data)
сравнивает указатели, а не фактические объекты. Пропустить объект Student
по значению для BST:
BST<Students> stree;
Кроме того, не передавайте объект по значению операторам и вашей функции поиска:
bool Students::operator< (const Students& ob)
TNode<DataType>* BST<DataType>::bstSearch(const DataType& search)
Следующее, что вы должны заметить, это то, что вам не нужно реализовывать все операции сравнения отдельно, достаточно реализовать только operator<
. Например:
bool operator==(const some_class& b){ return !(*this < b) && !(b < *this); }
bool operator>(const some_class& b){ return !(*this == b) && !(*this < b); }
// and so on...
С другой стороны, вы можете использовать шаблоны, std::enable_if
и std::is_pointer
чтобы автоматически разыменовать указатель:
#include <utility>
#include <iostream>
template<typename T>
T& dereference(T &v){return v;}
template<typename T>
const T& dereference(const T& v){return v;}
template<typename T>
typename std::enable_if<!std::is_pointer<T>::value, T&>::type dereference(T* v){return dereference(*v);}
// example usage:
template <typename T>
class A
{
public:
bool compare(T a, T b){
return dereference(a) < dereference(b);
}
};
int main()
{
int u = 10;
int *v = &u;
int i = 5;
int *j = &i;
A<int> a;
A<int*> b;
std::cout << a.compare(i, u) << std::endl;
std::cout << b.compare(j, v) << std::endl;
return 0;
}
Итак, просто добавьте шаблоны dereference
, и в вашей функции search
вы можете использовать его как:
template <class DataType>
TNode<DataType>* BST<DataType>::bstSearch(DataType search)
{
TNode<DataType>* y = root;
while (y!=NULL && dereference(search) != dereference(y->data))
{
if (dereference(search) < dereference(y->data))
{
y = y->left;
}
else
{
y = y->right;
}
}
return y;
}
Подробнее о методе разыскивания см. В замечательных ответах на мой вопрос здесь: Рекурсивный указатель разыменования
Если вы хотите сохранить это дерево указателей, вы хотите сравнить вот так:
if (*search < *(y->data)) {
То, как я это вижу, int
- это не указательный тип, а Students*
- типа указателя.
Если вы используете Students
вместо Students*
в своем дереве, он должен работать.
Кроме того, вы можете выполнить другую реализацию для обработки деревьев указателей.
BST<int>
.