繁体   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