基于价值和参考的比较算子的C ++多态性

时间:2011-10-04 15:30:50

标签: c++ operators polymorphism

我想比较两个派生自相同基类型但不是相同派生类的对象。所以我将==运算符设为虚拟并将其覆盖在派生类中。

当我将所有对象存储在基类型的数组中时,不会调用派生的实现,而是直接进入基本实现。但是,当数组是指向基类的类型指针,并且取消引用元素时,它确实有效。

请问某人请解释为什么会出现这种情况?它令我感到困惑; - )

enum eType {
  BASE_TYPE,
  DERIVED_TYPE
};

class A {
  eType mType;
public:
  A() : mType(BASE_TYPE) {}
  A(eType Type) : mType(Type) {}
  virtual bool operator == (A &Other) {
    return mType == Other.mType;
  }
};

class B : public A {
  int bVal;
public:
  B(int Val) : A(DERIVED_TYPE), bVal(Val) {}
  virtual bool operator == (A &Other) {
    if(!(A::operator ==(Other))) {
      return false;
    }
    B* myB = (B*)&Other;
    return bVal == myB->bVal;
  }
};

int main(int argc, char *argv[])
{
  A a1, a2;
  B b1(0);
  B b2(1);

  bool result = false;

  // Calls implementation in A
  result = (a1 == a2);
  // Calls implementation in B
  result = (b1 == b2);

  A aArray[2];
  aArray[0] = b1;
  aArray[1] = b2;

  // Calls implementation in A!
  result = (aArray[0] == aArray[1]);

  A *aRefArray[2];
  aRefArray[0] = &b1;
  aRefArray[1] = &b2;

  // Calls implementation in B
  result = ((*aRefArray[0]) == (*aRefArray[1]));

  return 0;
}

1 个答案:

答案 0 :(得分:5)

  A aArray[2];
  aArray[0] = b1;
  aArray[1] = b2;

当您这样做时,会发生 Object Slicing ,并且会剥离对象的派生部分。现在存储在数组中的对象现在只是作为Base类的对象。当然,调用operator函数的Base类版本。


  A *aRefArray[2];
  aRefArray[0] = &b1;
  aRefArray[1] = &b2;

适当地,保留派生类对象的type,因为存储在数组中的内容只是指向实际对象而不是对象本身的指针。
由于保留了对象的类型,因此在这种情况下将调用操作符函数的派生类版本。