【问题标题】:C++ Polymorphism of Comparison Operator by Value and by Reference按值和按引用的比较运算符的 C++ 多态性
【发布时间】:2011-10-04 15:30:50
【问题描述】:

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

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

有人可以解释为什么会发生这种行为吗?这让我感到困惑;-)

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

【问题讨论】:

  • 您希望如何比较不同类型的对象?
  • 切片问题见this question
  • 请注意,在切片问题旁边,比较和多态并不是那么简单,因为多态主要是关于让对象做某事。有 dynamic_cast 和双重分派的解决方案,但并不简单。
  • @MarkB 我想我说错了。我想要做的是比较具有相同基本类型的类型。因此,如果我将类型 B 与类型 C 进行比较,则将类型与 mType 成员进行比较。如果两个 mType 相同(即它们都是相同的派生类型),则应比较所有成员。

标签: c++ operators polymorphism


【解决方案1】:
  A aArray[2];
  aArray[0] = b1;
  aArray[1] = b2;

当你这样做时 Object Slicing 发生并且对象的派生部分被剥离。现在存储在数组中的对象现在仅表现为基类的对象。很自然,操作函数的基类版本会被调用。


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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-17
    • 2011-08-17
    • 2023-03-03
    • 2023-03-26
    • 1970-01-01
    • 1970-01-01
    • 2018-05-29
    • 1970-01-01
    相关资源
    最近更新 更多