C ++ Как приводить динамически производные классы

Для всех методов Asp.Net MVC вы можете установить объект viewData, который устанавливает дополнительные значения atrtibute в сгенерированный HTML:

@Html.EditorFor(
    modelItem => item.YourProperty, 
    new { htmlAttributes = new { @id="custom_id" } })

для получения дополнительной информации. this .

-1
задан Dimitar Mihaylov 18 January 2019 в 23:18
поделиться

2 ответа

Хорошо, этим утром я проснулся с ответом. Вместо того, чтобы реализовывать функцию посещения в NodeVisitor.cpp, где я не могу получить доступ к функциям Интерпретатора, я сделал функцию посещения виртуальной и реализовал ее в Interpreter.cpp

unsigned long int Interpreter::visit(AST* node)
{
  Number* number = dynamic_cast<Number*>(node);
  BinaryOperation* binOp = dynamic_cast<BinaryOperation*>(node);

  if (number)
  {
    return this->VisitNumber((Number*)node);
  }

  return this->VisitBinOp((BinaryOperation*)node);
}

Я думаю, мой мозг просто нужен какое-то время ... Записывался на работу в течение 8 часов, а потом дома в течение 4, то 12 часов подряд: D

0
ответ дан Dimitar Mihaylov 18 January 2019 в 23:18
поделиться

Примечание: хотя иногда может возникнуть необходимость dynamic_cast<>, имейте в виду, что его использование - это «кодовый запах».

В объектно-ориентированном программировании вы обычно не запрашиваете объект для его типа, а затем делаете что-то на основе этой информации. Вы говорите объекту делать то, что вам нужно, и он будет делать правильные вещи в зависимости от того, что это за объект.

Так почему бы просто не дать AST метод virtual unsigned long InterpreterVisit(Interpreter* interpreter), а вместо этого сделать

unsigned long Interpreter::visit(AST *node) {
    node->InterpreterVisit(this);
}

? Если вы хотите сохранить код интерпретатора отдельно от кода AST, вы также можете реализовать его как вложение, где у вас есть второй объект , принадлежащий узлу AST, который реализует InterpreterVisit(), а затем вы просто нужно одно место, которое создает правильный тип объекта вложения для этого типа (например, с использованием частичной специализации шаблона).

Я не знаю достаточно о структуре вашего переводчика, чтобы сказать, работает ли это для вашего дизайна, но я хотел бы призвать вас остановиться и подумать, есть ли лучший способ, чем dynamic_cast<>, когда вы чувствуете искушение используйте его.

Иногда это также может помочь просто «спрятать» использование состава, особенно если вы обнаружите, что делаете то же самое часто. Сделай это один раз, заранее. Прикрепите объект к объектам на основе этого приведения, затем просто вызывайте этот объект вместо того, чтобы приводить его снова и снова.

PS: Что касается вашего циркуляра, иногда вы можете избежать таких ситуаций. Существует несколько инструментов:

  1. Объявите вперед один из классов, использующих class Foo; (обратите внимание на точку с запятой) вместо включения его заголовка. Это скажет C ++, что класс с таким именем существует без извлечения всего заголовка и использования другого класса. Вы не можете объявить подклассы объявленного заранее класса, но вы можете объявлять ссылки и указатели на него.

  2. Разделите ваши заголовки. Обычно каждый класс получает свой собственный заголовок (.h / .hpp) и файл реализации (.cp / .cpp). Таким образом, вы можете включить только те классы, которые вам нужны, и заранее объявить эти классы в заголовках других (и затем только фактически включить полный заголовок в файлы реализации, которые используют эти классы).

  3. Разделите ваши классы сами. То есть иметь один класс MixinA с классом деталей A, который необходимо включить, другой класс MixinB с классом деталей B должен включить, а затем создать class C : public MixinA, public MixinB .... Таким образом, у вас есть класс, который делает оба, но избегает круга, потому что только C может увидеть всю картину.

0
ответ дан uliwitness 18 January 2019 в 23:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: