Могу ли я научить dynamic_cast <> () новым трюкам? - PullRequest
1 голос
/ 11 августа 2010

Есть ли в C ++ способ сконструировать ваш класс таким образом, чтобы с помощью указателя на ваш класс вы могли дать указание dynamic_cast <> () как привести к другому классу, для которого вы переносите реализацию? Будет ли оператор бросок сделать трюк? Представьте, что у меня есть базовый класс интерфейса Abstract, и я извлекаю конкретный A из этого, а также concreteB, но concreteB оборачивает интерфейс в объект типа concreteA. Если я получу запрос на приведение к бетону из бетона А, я бы хотел, чтобы он работал:

class Abstract {
public:
  virtual void interface() = 0;

};

class concreteA : public Abstract {
public:
  virtual void interface();

};

class concreteB : public Abstract {
public:
  concreteB(concreteA &underlying)
    : _underlying(&underlying) {
  }
  virtual void interface();

  operator concreteA*() {
    return _underlying;
  }

private:
  concreteA *_underlying;

};

void
myTest() {
  concreteA myClassA;
  concreteB myClassB(myClassA);
  Abstract *abstract = &myClassB;
  concreteA *underlying = dynamic_cast<concreteA *>(abstract);
}

1 Ответ

4 голосов
/ 11 августа 2010

Нет. Динамическое приведение говорит компилятору: «Я вообще не хочу менять этот объект, я просто хочу попытаться посмотреть на него, как если бы это был другой тип, но не меняйте его. Если вам нужно изменить его , вернуть NULL или выдать исключение. " Динамическое приведение не будет пытаться выполнить какие-либо такие преобразования от вашего имени. Для этого вам нужно static_cast или boost::lexical_cast.

Это потому, что оператор приведения может:

  • Переосмыслить существующий объект по-новому, не меняя его
  • Изменить объект каким-либо образом, чтобы привести его к другому типу, например, int -> short или double -> int.

и один вызов может выполнить только один из них, но не оба.

Для получения дополнительной информации о «двойственной» природе оператора приведения вы можете увидеть эту статью Эрика Липперта , которая нацелена на C #, но в основном относится и к C ++.

В частности, вы можете увидеть § 5.2.7 в самой последней версии C ++ 0x - это поведение не изменилось по сравнению с C ++ 03.

...