【问题标题】:Operator Overloading with Templates inside of a BST在 BST 中使用模板重载运算符
【发布时间】:2011-07-02 12:51:42
【问题描述】:

我目前有一个二叉搜索树设置,使用模板让我可以轻松更改二叉搜索树中的数据类型。目前,我无法重载包含要存储在树中的数据的 studentRecord 类。我需要重载此类中的比较运算符,以便我的 BST 可以根据其中一个内容(在本例中为学生 ID)正确比较两个对象。但是,尽管在 studentRecord 中重载了运算符,但仍然没有进行正确的比较。

详情如下:

此时,bst 对象 studentTree 已创建,类型为

bst<studentRecord *> studentTree;

studentRecord 是以下类:

// studentRecord class
class studentRecord{
public:
    // standard constructors and destructors
    studentRecord(int studentID, string lastName, string firstName, string academicYear){ // constructor
        this->studentID=studentID;
        this->lastName=lastName;
        this->firstName=firstName;
        this->academicYear=academicYear;
    }

    friend bool operator > (studentRecord &record1, studentRecord &record2){
        if (record1.studentID > record2.studentID)
            cout << "Greater!" << endl;
        else
            cout << "Less then!" << endl;
        return (record1.studentID > record2.studentID);
    }

private:
    // student information
    string studentID;
    string lastName;
    string firstName;
    string academicYear;
};

每当向我的 BST 添加新项目时,都必须相互比较。因此,我想重载 studentRecord 类,以便在发生此比较过程时,比较学生 ID(否则将进行无效比较)。

但是,我的插入函数从不使用重载的比较函数。相反,它似乎是以其他方式比较这两个对象,导致 BST 中的排序无效。下面是我的插入函数的一部分——重要的是要注意,由于模板过程的发生,toInsert 和 nodePtr->data 都应该是 studentRecord 类型。

// insert (private recursive function)
template<typename bstType>
void bst<bstType>::insert(bstType & toInsert, bstNodePtr & nodePtr){
    // check to see if the nodePtr is null, if it is, we've found our insertion point (base case)
    if (nodePtr == NULL){
        nodePtr = new bst<bstType>::bstNode(toInsert);
    }

    // else, we are going to need to keep searching (recursive case)
    // we perform this operation recursively, to allow for rotations (if AVL tree support is enabled)
    // check for left
    else if (toInsert < (nodePtr->data)){ // go to the left (item is smaller)
        // perform recursive insert
        insert(toInsert,nodePtr->left);

        // AVL tree sorting
        if(getNodeHeight(nodePtr->left) - getNodeHeight(nodePtr->right) == 2 && AVLEnabled)
            if (toInsert < nodePtr->left->data)
                rotateWithLeftChild(nodePtr);
            else
                doubleRotateWithLeftChild(nodePtr);
    }

另外,这里是 BST 类定义的一部分

// BST class w/ templates
template <typename bstType>
class bst{

private: // private data members

    // BST node structure (inline class)
    class bstNode{
    public: // public components in bstNode

        // data members
        bstType data;
        bstNode* left;
        bstNode* right;

        // balancing information
        int height;

        // constructor
        bstNode(bstType item){
            left = NULL;
            right = NULL;
            data = item;
            height = 0;
        }

        // destructor
        // no special destructor is required for bstNode     
    };

    // BST node pointer
    typedef bstNode* bstNodePtr;

public: // public functions.....

关于可能导致此问题的任何想法?我是否重载了错误的类或错误的函数?感谢您提供任何帮助——我似乎迷路了,因为同时发生了许多不同的事情。

【问题讨论】:

    标签: c++ templates operator-overloading binary-tree binary-search-tree


    【解决方案1】:

    你像这样实例化你的模板类:

    bst<studentRecord *> studentTree;
    

    所以 bstType == studentRecord*

    插入看起来像这样:

    template<studentRecord*>
    void bst<studentRecord*>::insert(studentRecord*& toInsert, bst<studentRecord*>::bstNodePtr & nodePtr);
    

    所以你正在做一个指针比较,这就是为什么你的操作员没有像 Asha 指出的那样被调用。

    更多所以你只重载大于运算符(>),但在插入时你使用小于运算符(

    更多,所以我可以指出您代码中的几个问题:

    1. studentRecord.studentID 是字符串类型吗?但是,您尝试在构造函数中为其分配一个整数。这将简单地将整数转换为 char 并将字符分配给字符串 - 所以很可能不是您想要的。
    2. 您缺少小于运算符。

    下面的代码和一些演示操作符的代码在比较两个学生记录类型的实例时被调用。您还可以通过在 studentRecord 类中注释运算符定义来查看缺少小于运算符的影响(-> 编译错误)。

    class studentRecord
    {
    public:
    
        studentRecord(int studentID) : studentID(studentID)
        { 
        }
    
        bool operator > (studentRecord &record)
        {
            return (studentID > record.studentID);
        }
    
        /* Uncomment to get rid of the compile error!
        bool operator < (studentRecord &record)
        {
            return studentID < record.studentID;
        }
        */
    
    private:
        // student information
        int studentID;
    };
    
    int main()
    {
        studentRecord r1(10);
        studentRecord r2(5);
    
        if ( r1 < r2 )
        {
            cout << "It works! " << "r1 less than r2" << endl;
        }
        else
        {
            cout << "It works! " << "r1 greater than r2" << endl;
        }
    
        if ( r1 > r2 )
        {
            cout << "It works! " << "r1 greater than r2" << endl;
        }
        else
        {
            cout << "It works! " << "r1 less than r2" << endl;
        }
    }
    

    作为结束注释,最好也提供其他比较运算符(>=、

    【讨论】:

    • 说实话,我的原始代码中确实有额外的重载运算符。但是,我只是没有将它们包含在我的帖子中,以减少人们需要阅读以帮助我解决问题的内容量。
    【解决方案2】:

    你的树是一棵指针的树。因此,当您尝试将元素插入树时,会比较 pointers 的值。所以你的重载运算符不会被调用。如果要使用重载运算符,则应创建bst&lt;studentrecord&gt;

    【讨论】:

    • 我为我之前的评论道歉——你的回答是正确的。一开始我只是误解了你的回答。
    猜你喜欢
    • 2018-08-03
    • 2023-03-16
    • 2016-04-04
    • 2023-03-03
    • 2015-09-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多