为什么这个代码会被一个"纯虚函数调用" Visual Studio下的错误

时间:2015-07-27 19:17:31

标签: c++

以下代码在g ++ 5.1上运行正常,但在Visual Studio 2013或2015下运行时," R6025纯虚函数调用"在Test().GetCollection()

中调用main()时出错
#include <iostream>

template <typename T>
class MoveNextCollection
{
    // Forward declaration
    class ConstIterator;

public:
    // Usual C++ collection typedefs
    typedef T value_type;
    typedef const value_type& const_reference;
    typedef ConstIterator const_iterator;

    const_iterator begin() const
    {
        if (MoveToStart(&_CurrentValue))
        {
            return const_iterator(this);
        }
        else
        {
            return end();
        }
    }

    const_iterator end() const
    {
        return const_iterator();
    }

    virtual ~MoveNextCollection()
    {

    }

private:

    class ConstIterator
    {
    public:
        ConstIterator(const MoveNextCollection *pMoveNextCollection = nullptr)
            : _pMoveNextCollection(pMoveNextCollection)
        {
        }

        const_reference operator*() const
        {
            return _pMoveNextCollection->GetCurrentValue();
        }

        bool operator==(const ConstIterator &iter) const
        {
            return (_pMoveNextCollection == iter._pMoveNextCollection);
        }

        bool operator!=(const ConstIterator &iter) const
        {
            return !operator==(iter);
        }

        ConstIterator &operator++()
        {
            if (!_pMoveNextCollection->MoveToNext())
            {
                _pMoveNextCollection = nullptr;
            }

            return (*this);
        }

    private:
        const MoveNextCollection *_pMoveNextCollection;
    };

    const_reference GetCurrentValue() const
    {
        return _CurrentValue;
    }

    bool MoveToNext() const
    {
        return MoveToNext(&_CurrentValue);
    }

private:
    virtual bool MoveToStart(value_type *) const = 0;
    virtual bool MoveToNext(value_type *) const = 0;

    mutable value_type _CurrentValue;
};

class Test
{
public:

    class Collection : public MoveNextCollection<int>
    {
    private:
        bool MoveToStart(int *pValue) const override
        {
            *pValue = 314; // Whatever
            return true;
        }

        bool MoveToNext(int *) const override
        {
            return false;
        }
    };

    const Collection& GetCollection() const
    {
        return _collection;
    }

private:
    Collection _collection;
};

int main()
{
    for (int val : Test().GetCollection())
    {
        std::cout << val << "\n";
    }

    return 0;
}

但是,只有在类&#34; MoveNextCollection&#34;中的虚拟析构函数时才会出现这种情况。存在。否则运行正常(当析构函数被注释掉时)。请注意,上述错误发生在Visual Studio的桌面版本中,但如果您在http://webcompiler.cloudapp.net/运行代码,它只会显示错误-1073740791(我认为它的错误相同)。请注意,为了发布这个帖子,代码已经被删除了它的基本要点(对不起,不能让它更短)。这是VS的错误吗?对于任何反馈,我们都表示感谢。感谢。

1 个答案:

答案 0 :(得分:2)

基于范围的表达式:

_playerLayer.player.actionAtItemEnd = AVPlayerActionAtItemEndNone;

相当于:

for (int val : Test().GetCollection())

{ auto&& __range = Test().GetCollection(); // (1) for ( auto __begin = begin(__range), // (2) __end = end(__range); __begin != __end; ++__begin ) { int val = *__begin; // etc } } 会返回对GetCollection()的引用,但Test::_collection对象超出了第(1)行中表达式末尾的范围 - 所以你要离开(2)悬挂的参考文献。之后的一切都是未定义的行为。它&#34;工作&#34;只是未定义行为的一种可能结果。

如果Test看起来像:

GetCollection()

引用的临时绑定的生命周期将在引用的生命周期中延长,这将是整个基于范围的表达式。在该场景中没有未定义的行为。