簡體   English   中英

指向嵌套類的指針的加法運算符重載

[英]Addition operator overload for pointers to nested classes

我正在研究一個包含私有嵌套節點類的鏈表類。 我想通過使用重載加法運算符在列表中前移n個節點,但是clang給我一個錯誤“重載的'operator +'必須是一元或二進制運算符(具有3個參數)”。 我認為當您將其聲明為朋友函數時,隱式此參數便消失了。

首先是我的頭文件

 template <class T>
 class List
    {

  private:

    class ListNode
    {
      public:

        ListNode();


        ListNode(const T& ndata);


        friend ListNode* operator+(const ListNode* &node, int n);

        ListNode* next;

        ListNode* prev;

    };

  public:
    friend ListNode* operator+(const ListNode* &node, int n);

我的實現如下:

template <class T>
typename List<T>::ListNode* List<T>::ListNode::operator+(const ListNode* &node, int n)
{
    ListNode* current = node;

    while (n--){
        if (current->next != 0)
            current = current->next;
    }
    return current;
}

從根本上講,您要執行的操作的問題在於,它使指針上的運算符過載。 這是有問題的 為此,將盡可能簡化代碼,但不會建立以下代碼:

class foo{};

foo *operator+(foo *, int) {
    return nullptr;
}

int main() {}

嘗試給出:

$ g++ gl.cpp 
gl.cpp:5:26: error: ‘foo* operator+(foo*, int)’ must have an argument of class or enumerated type
 foo *operator+(foo *, int) {

如果您確實要使用operator+ ,那么最簡單的方法可能是使用成員運算符形式:

template<class T>
class List {
    class ListNode {        ...
    public:
        ListNode &operator+(int n) {
            ListNode *current = this;

            while (n--)
               if (current->next != 0)
                   current = current->next;

           return *current;
        }
    };
    ...
};

但是,這有點讓人產生誤解,因為您實際上沒有在節點上添加整數,而是在獲取下一個節點。 next方法可能更清晰:

template<class T>
class List {
    class ListNode {        ...
    public:
        ListNode *next(int n) {
            ListNode *current = this;

            while (n--)
                if (current->next != 0)
                   current = current->next;

            return current;
        }
    };
    ...
};

如前所述,在指針上重載運算符是有問題的,同樣,最簡單的方法是使operator+成為成員函數。 但是,有一種方法可以獲取您想要的行為...

訣竅是將指針包裝在行為類似於指針的對象中(通常稱為iterator )。

一個工作示例來演示:

class List {
    struct Node {
        Node* next; int data;
    };
    Node* m_head{0};

public:
    // the fake pointer type.
    struct Iter {
        Iter(Node* initial = 0)
            : m_base(initial) {}
        Node* operator->()
        { return m_base; }
        bool operator!=(const Iter& other) const
        { return m_base != other.m_base; }
    private:
        Node* m_base;
    };

    // get head as fake pointer.
    Iter head()
    { return m_head; }
    void push_front(const int&);
};

void List::push_front(const int& x)
{
    Node* n = new Node;
    n->data = x;
    n->next = m_head; m_head = n;
}

// non-member operator.
List::Iter operator+(List::Iter i, int count)
{
    for ( ; count > 0 && i != 0; count-- )
        i = i->next;
    return i;
}

int main(int argc, char* argv[])
{
    List list;
    for ( int i = 0; i < 10; i++ )
        list.push_front(i);
    for ( auto i = list.head(); i != 0; i = i+1 )
        std::cout << i->data << ' ';
    std::cout << std::endl;
    return 0;
}

有關更高級的示例,請參見此處

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM