gpt4 book ai didi

c++ - 为什么重写类的指针使用基类的 operator== 和 operator!=

转载 作者:太空宇宙 更新时间:2023-11-04 16:12:24 28 4
gpt4 key购买 nike

我有类的迭代器模板和用于 for 语句的类。

template<class T>
class Itr2 {
public:
Itr2() { }
~Itr2() { }

typedef typename Itr2 type;
typedef typename T& reference;

virtual type& operator++() { return *this; }
virtual T& operator*() { return ((reference)*((type*)this)); }
virtual bool operator==(const type& o) const { return true; }
virtual bool operator!=(const type& o) const { return false; }
};


template<class T>
class I2
{
public:
typedef I2<T> type;
typedef T value;
typedef T& reference;
typedef typename Itr2<T> iterator;

virtual iterator& begin() { return *(new iterator()); }
virtual iterator& end() { return *(new iterator()); }
};

接下来,我为标准 std::vector<> 创建了类。

template<class T>
class ItrSTD : public Itr2<T> {
public:
typedef typename Itr2<T> base_type;
typedef typename ItrSTD<T> type;
typedef typename T& reference;
typedef typename std::vector<T>::iterator std_itr;
protected:
std_itr itr_;
public:
ItrSTD(const type& o) { itr_ = o.itr_; }
ItrSTD(const std_itr& o) { itr_ = o; }

virtual base_type& operator++() { itr_++; return *this; }

virtual T& operator*() { return ((reference)(*this->itr_)); }
bool operator==(const base_type& o) const override { return (((const type&)o).itr_ == this->itr_); }
bool operator!=(const base_type& o) const override { return (((const type&)o).itr_ != this->itr_); }
};



template<class T>
class VSTD : public I2<T> {
protected:
std::vector<T> arr_;
public:
typedef typename ItrSTD<T> iterator;

VSTD(const VSTD& o) { arr_ = o.arr_; }
template<typename ...E> VSTD(E&&...e) : arr_({ std::forward<T>(e)... }) { }

iterator& begin() _NOEXCEPT override{ return (*new iterator(arr_.begin())); }
iterator& end() _NOEXCEPT override{ return (*new iterator(arr_.end())); }

};

如果我使用直接语句 for(int i:v)。它工作正常,但是当我尝试从指针编译器执行此操作时,使用基类运算符!=(不覆盖运算符!=)并且代码不起作用:(。

int v_i = 0;
VSTD<int> vstd_a = { 1, 2, 3 };
I2<int> *i2 = &vstd_a;

for (int j : *i2) //DOESN't work :( use operator!= from base class
{
v_i += j;
}
for (int j : vstd_a) //work fine :) use operator!= from VSTD.
{
v_i += j;
}

如果我简化代码:

template<typename T>
class I3
{
public:
T i;
virtual bool operator==(const I3& o) const { return false; }
};

template<typename T>
class I3O : public I3<T>
{
public:
virtual bool operator==(const I3& o) const override { return true; }
};

I3O<int> i3_a, i3_b; I3<int> *i3_ap, *i3_bp;

i3_ap = &i3_a; i3_bp = &i3_b; bool i3_c;

i3_c = (i3_a == i3_b);
i3_c = ((*i3_ap) == (*i3_bp));

两个结果都很好(返回 true)并与重写类进行比较(仅对于( : )工作不好 :( :

为什么会这样。模板指针可以用于语句吗?begin()、end() 函数工作正常。只有运营商工作不同。

附言我使用 VS2013 编译器。

最佳答案

我没有看过你代码中的细节,但是......看起来像您正在尝试使迭代器多态。标准然而,不断地按值传递它们,而按值传递不会支持多态;它切片。因此(我假设),在:

for ( int j : *i2 )

编译器为迭代器创建局部变量,其类型为静态地确定。尽管它调用了正确的 begin(),它将结果分配给这个局部变量,从而对其进行切片。

如果你需要多态迭代器,你需要实现信/信封成语:

class Iterator
{
Iterator* myImpl;

virtual Iterator* clone() const { abort(); }
virtual T& current() const { abort(); }
virtual bool isEqual( Iterator const* other ) { abort(); }
virtual void next() { abort(); }

protected:
Iterator() : myImpl( nullptr ) {}
public:
Iterator( Iterator* impl ) : myImpl( impl ) {}
Iterator( Iterator const& other ) : myImpl( other.clone() ) {}
virtual ~Iterator() { delete myImpl; }

T& operator*() const
{
return myImpl->current();
}
bool operator==( Iterator const& other ) const
{
return myImpl->isEqual( other.myImpl );
}
Iterator& operator++()
{
myImpl->next();
return *this;
}
// ...
};

class DerivedIterator : public Iterator
{
Iterator* clone() const override { return new DerivedIterator( *this ); }
T& current() const override { ... }
bool isEqual( Iterator const* other ) override { ... }
virtual void next() { ... }
public:
DerivedIterator(...) ...
};

然后,您派生的 beginend 返回如下内容:

Iterator( new DerivedIterator(...) );

这在运行时相当昂贵,但它确实是唯一的方法提供多态性并且仍然具有迭代器。

关于c++ - 为什么重写类的指针使用基类的 operator== 和 operator!=,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26995999/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com