在导出类中的Operator ==不会被调用 [英] Operator== in derived class never gets called

查看:175
本文介绍了在导出类中的Operator ==不会被调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人可以让我远离我的痛苦吗?我想弄清楚为什么一个派生operator ==永远不会在循环中被调用。为了简化示例,这里是我的Base和Derived类:

  class Base {// ... snipped 
bool operator ==(const Base& other)const {return name_ == other.name_; }
};

class Derived:public Base {// ... snipped
bool operator ==(const Derived& other)const {
return(static_cast< const Base&> * this)==
static_cast< const Base&>(other)?age_ == other.age_:
false);
};

现在当我实例化和比较这样...

 派生p1(Sarah,42); 
派生p2(Sarah,42);
bool z =(p1 == p2);

...一切正常。这里的操作符== from Derived被调用,但是当我循环遍历列表时,将指针列表中的项目与Base对象进行比较...

  list< Base *>科尔

coll.push_back(new Base(fred));
coll.push_back(new Derived(sarah,42));
// ... snipped

//从列表中获取两个项目。
Base& obj1 = ** itr
Base& obj2 = ** itr2;

cout<< obj1.asString()<< < ((obj1 == obj2)?==:!=)<
<< obj2.asString()<< endl

这里 asString()这里为简洁没有显示)工作正常,但 obj1 == obj2 总是调用 Base Derived


$ b $ b

我知道当我发现有什么问题时我会踢自己的,但是如果有人能轻轻地让我下来,那将是非常感激。

解决方案

有两种方法可以解决这个问题。



第一个解决方案到循环,所以你知道当你有一个 Base ,当你有一个 Derived 。如果你真的只处理 Derived 对象,请使用

  ; Derived *>科尔

否则在某处放置 dynamic_cast p>

第二个解决方案。在运算符== 中加入相同的逻辑。首先使其为虚拟,所以左边的操作数的类型在运行时确定。然后手动检查右侧操作数的类型。

  virtual bool operator ==(const Base& other)const {
if(!Base :: operator ==(other))return false;
Derived * other_derived = dynamic_cast<派生*>(&其他);
if(!other_derived)return false;
return age_ == other_derived-> age_;
}

但是考虑到不同类型的对象可能不会相等,你想要的是

  virtual bool operator ==(const Base& other)const {
Derived * other_derived = dynamic_cast<派生*>(&其他);
return other_derived
&& Base :: operator ==(other)
&& age_ == other_derived-> age_;
}


Can someone please put me out of my misery with this? I'm trying to figure out why a derived operator== never gets called in a loop. To simplify the example, here's my Base and Derived class:

class Base { // ... snipped
  bool operator==( const Base& other ) const { return name_ == other.name_; }
};

class Derived : public Base { // ... snipped
  bool operator==( const Derived& other ) const { 
    return ( static_cast<const Base&>( *this ) ==
             static_cast<const Base&>( other ) ? age_ == other.age_ :
                                                 false );
};

Now when I instantiate and compare like this ...

Derived p1("Sarah", 42);
Derived p2("Sarah", 42);
bool z = ( p1 == p2 );

... all is fine. Here the operator== from Derived gets called, but when I loop over a list, comparing items in a list of pointers to Base objects ...

list<Base*> coll;

coll.push_back( new Base("fred") );
coll.push_back( new Derived("sarah", 42) );
// ... snipped

// Get two items from the list.
Base& obj1 = **itr;
Base& obj2 = **itr2;

cout << obj1.asString() << " " << ( ( obj1 == obj2 ) ? "==" : "!=" ) << " "
     << obj2.asString() << endl;

Here asString() (which is virtual and not shown here for brevity) works fine, but obj1 == obj2 always calls the Base operator== even if the two objects are Derived.

I know I'm going to kick myself when I find out what's wrong, but if someone could let me down gently it would be much appreciated.

解决方案

There are two ways to fix this.

First solution. I would suggest adding some extra type logic to the loop, so you know when you have a Base and when you have a Derived. If you're really only dealing with Derived objects, use

list<Derived*> coll;

otherwise put a dynamic_cast somewhere.

Second solution. Put the same kind of logic into your operator==. First make it virtual, so the type of the left-hand operand is determined at runtime. Then manually check the type of the right-hand operand.

virtual bool operator==( const Base& other ) const {
  if ( ! Base::operator==( other ) ) return false;
  Derived *other_derived = dynamic_cast< Derived * >( &other );
  if ( ! other_derived ) return false;
  return age_ == other_derived->age_;
}

but considering that objects of different types probably won't be equal, probably what you want is

virtual bool operator==( const Base& other ) const {
  Derived *other_derived = dynamic_cast< Derived * >( &other );
  return other_derived
   && Base::operator==( other )
   && age_ == other_derived->age_;
}

这篇关于在导出类中的Operator ==不会被调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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