C ++ Полиморфизм оператора сравнения по значению и по ссылке - PullRequest
0 голосов
/ 04 октября 2011

Я хочу сравнить два объекта, которые являются производными от одного базового типа, но не относятся к одному и тому же производному классу. Поэтому я сделал оператор == виртуальным и переопределил его в производных классах.

Когда я сохраняю все свои объекты в массиве базового типа, производная реализация не вызывается, она сразу переходит к базовой реализации. Однако он работает, когда массив имеет указатель типа на базовый класс и отменяет ссылку на элементы.

Может кто-нибудь объяснить, почему происходит такое поведение? Это сбивает с толку меня; -)

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 Ответ

5 голосов
/ 04 октября 2011
  A aArray[2];
  aArray[0] = b1;
  aArray[1] = b2;

При этом происходит разделение объекта , и производная часть объекта просто удаляется.Объекты, теперь хранящиеся внутри массива, теперь просто ведут себя как объекты базового класса.И, естественно, вызывается версия функции оператора Базового класса.


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

Соответственно, сохраняет type объектов производного класса, потому что то, что хранится в массиве, является просто указателемфактический объект, а не сам объект.
Поскольку тип объекта сохраняется, в этом случае вызывается версия производного класса операторных функций.

...