为什么来自重写类的指针使用operator ==和operator!= from base class [英] Why pointer from override class use operator== and operator!= from base class

查看:98
本文介绍了为什么来自重写类的指针使用operator ==和operator!= from base class的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有用于for语句的类和类的Iterator模板。

I have Iterator template for class and class for use in the for statement.

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<>创建了类。



Next, I created class for standard 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())); }

};





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





If i use direct statement for(int i:v). It is works fine, but when I try to do this from the pointer compiler use base class operator!= (not override operator!=) and code doesn't work :(.

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





为什么这样发生。可以用于州模板指针的设置?

begin(),end()函数工作正常。只有操作员工作不同。

P.S.我使用的是VS2013编译器。





一些额外的信息:



如果我简化了代码:





Why this happen. It is possible to use for statement for template pointer ?
begin(), end() functions works fine. Only operator work different.
P.S. I use VS2013 compiler.


Some additional info:

If i simplify the code:

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





两个结果都很好(返回true)并从override类比较(仅适用于(:)工作坏:():





Both result are fine (return true) and compare from override class (only for( : ) work bad :():

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

推荐答案

可能因为当你这样做



Possibly because when you do this

for(int j : *i2)





对I2类型有一个隐藏的强制转换,所以当编译器查找vTable他得到了基类之一。



也就是说,如果你拿一个子类的指针并把它投给它的一个父亲你就可以使用他们导出的vTable。



BTW这是一个相当新的C ++标准,不是吗?我坚持使用C ++ / 98我暂时没有关于这种结构的第一手经验,我根据我遇到的类似手工制作的错误(或功能)进行推测。



希望有所帮助,

Denis



there is a hidden cast to the type I2, so when the compiler looks for the vTable he gets the one of the base class.

That is, if you take a pointer of a child class and cast it to one of its fathers you get to use their exported vTable.

BTW this is a fairly recent C++ standard, isnt it? I'm stuck with C++/98 for the time being so I don't have first-hand experience on that kind of constructs, I am speculating on the basis of similar hand-crafted bugs (or features) I encountered.

Hope that helps,
Denis


这篇关于为什么来自重写类的指针使用operator ==和operator!= from base class的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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