带有抽象基类和Wall的operator ++(int)重载 [英] operator++(int) overload with abstract base class and Wall

查看:78
本文介绍了带有抽象基类和Wall的operator ++(int)重载的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am currently creating a set of iterators which will differ in implementation detail, but will be used in the same algorithms. For this reason, they must all have the same interface. To achieve this, I created an abstract iterator class and inherited from this class in all further iterators.

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

This should give you an idea of what my code looks like:

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运算符重载(使用-Wall -Werror编译):我的operator ++(int)实现引发警告(gcc 4.8.0),该警告是返回对临时引用的引用。链接问题中的解决方案是只返回对象而不是引用。

Now I am facing the same problem as in C++ post-increment operator overload in iterators (compiling with -Wall -Werror): My operator++(int) implementation throws a warning (gcc 4.8.0) that a reference to a temporary is returned. The solution in the linked question was to just return the object instead of the reference.

但是,这对我不起作用。如果我同时更改接口和派生类以返回对象而不是引用,则会出现以下错误(摘录,其他文件名等已删除):

However, this will not work for me. If I change both interface and derived class to return an object instead of a reference, the following errors appear (excerpt, additional file names etc. removed):

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;
                           ^

将返回类型更改为派生类而不是抽象类上的对象可能会返回指定的返回类型冲突错误。

Changing the return type to object on the derived class but not on the abstract class expectedly returns a "conflicting return type specified" error.

我该如何进行这项工作?

How can I make this work?

推荐答案

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

Try to change design: let's NodeIterator holds INodeIterator as a pointer. All methods of NoteIterator will delegates to the holding INodeIterator object. In that case you can use correct signature:

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;
}

这篇关于带有抽象基类和Wall的operator ++(int)重载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆