我目前正在创建一组迭代器,这些迭代器的实现细节有所不同,但是将在相同的算法中使用。因此,它们必须都具有相同的接口(interface)。为此,我创建了一个抽象的迭代器类,并在所有其他迭代器中从该类继承。

这应该使您了解我的代码是什么样的:

class INodeIterator
{
public:
    virtual ~INodeIterator() {};
    virtual bool operator!= (const INodeIterator& other) =0;
    virtual bool operator== (const INodeIterator& other) =0;
    virtual INodeIterator& operator++ () =0;
    virtual INodeIterator& operator++ (int i) =0;
    virtual Node& operator* () =0;
};

class NodeIterator : public INodeIterator
{
public:
    /* snip */
    NodeIterator& operator++ (int i)
    {
        NodeIterator tmp(*this);
        ++(*this);
        return(tmp);
    }
};

现在,我面临着与C++ post-increment operator overload in iterators (compiling with -Wall -Werror)中相同的问题:我的operator ++(int)实现引发了一个警告(gcc 4.8.0),该警告返回了对临时引用的引用。链接问题中的解决方案是仅返回对象而不是引用。

但是,这对我不起作用。如果我同时更改接口(interface)和派生类以返回对象而不是引用,则会出现以下错误(摘录,其他文件名等被删除):
INodeIterator.h:16:27: error: invalid abstract return type for member function ‘virtual INodeIterator INodeIterator::operator++(int)’
     virtual INodeIterator operator++ (int i) =0;
                           ^

NodeIterator.h:33:22: error: invalid covariant return type for ‘virtual NodeIterator NodeIterator::operator++(int)’
         NodeIterator operator++ (int i);
                      ^

INodeIterator.h:16:27: error:   overriding ‘virtual INodeIterator INodeIterator::operator++(int)’
     virtual INodeIterator operator++ (int i) =0;
                           ^

将返回类型更改为派生类上的对象,而不是抽象类上的对象,预期会返回“指定了冲突的返回类型”错误。

我该如何工作?

最佳答案

尝试更改设计:让我们的NodeIterator持有INodeIterator作为指针。 NoteIterator的所有方法都将委托(delegate)给保持INodeIterator对象。在这种情况下,您可以使用正确的签名:

struct IteratorInterface {
    virtual ~IteratorInterface() {}
    virtual std::unique_ptr<IteratorInterface> clone() const = 0;
    virtual void next() = 0;
};

class Iterator {
    std::unique_ptr<IteratorInterface> impl;
public:
    Iterator(std::unique_ptr<IteratorInterface> r) : impl(std::move(r)) {}
    Iterator(const Iterator &r) : impl(r.impl->clone()) {}
    Iterator& operator++() {
        impl->next();
        return *this;
    }
    Iterator operator++(int ) {
        Iterator tmp(*this);
        impl->next();
        return tmp;
    }
    void swap(Iterator &other) {
        other.impl.swap(impl);
    }
};

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
    struct IteratorInterfaceImpl : IteratorInterface {
        int i;
        IteratorInterfaceImpl() : i(0) {}
        virtual std::unique_ptr<IteratorInterface> clone() const {
            return std::unique_ptr<IteratorInterface>(new IteratorInterfaceImpl(*this));
        }
        virtual void next() {
            i += 1;
        }
    };
    Iterator tmp(std::unique_ptr<IteratorInterface>(new IteratorInterfaceImpl()));
    tmp++;
    ++tmp;

    return 0;
}

关于c++ - 带有抽象基类和Wall的operator++(int)重载,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16685604/

10-10 13:49
查看更多