Варианты дизайна класса с использованием безопасного даункинга - PullRequest
1 голос
/ 21 марта 2011

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

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

Этот код предназначен для мобильного телефона, поэтому использование большого количества динамических_кастов может быть неэффективным.

Код является новым и не задуман как камень, и поэтому его можно улучшить (я не писал его, я только что присоединился к компании и работаю над ним, поэтому не хочу полностью его разрывать).

Какие есть варианты для хорошего дизайна / использования?(Его c ++, но с использованием проверки типов и прямого преобразования c (чтобы избежать накладных расходов на dynamic_casts) кажется немного старомодным).

Есть ли какое-то преимущество в добавлении функций типа CastToXXX () в базовый класс, например?

Типы производных классов, скорее всего, будут фиксированными.

Ответы [ 3 ]

2 голосов
/ 21 марта 2011

dynamic_cast не такой медленный, и вы, вероятно, не сможете добиться большего успеха.Профиль и доказать, что это узкое место производительности, прежде чем искать альтернативные решения.Никогда ничего не делай, потому что, возможно, ты где-то слышал, что это может быть медленно.

1 голос
/ 22 марта 2011

Пусть базовый класс в древовидной структуре имеет чисто виртуальный метод Visit ().

class CBase {
  virtual void Visit(CVisitor* visitor) const = 0;
};

Пусть унаследованные классы реализуют его:

class CFoo : public CBase {
  virtual void Visit(CVisitor* visitor) const {
    visitor->Accept(this);
  }
};

class CBar : public CBase {
  virtual void Visit(CVisitor* visitor) const {
    visitor->Accept(this);
  }
};

Финальная магия:

class CVisitor {
  void Accept(CFoo* foo) {
    // operate on CFoo*
  }
  void Accept(CBar* bar) {
    // operate on CBar*
  }
};

Поэтому все, что вам нужно сделать, - это создать методы Accept и Visit для новых типов и пройти по дереву с помощью класса CVisitor, а затем вы можете работать с любым типом в дереве без any Приведение указателя.

Надеюсь, это поможет.

Приветствия

1 голос
/ 21 марта 2011

Если dynamic_cast / RTTI не является опцией, простой способ справиться с ситуацией такого типа - использовать Шаблон посетителя

По сути, вы определяете базовый класс, который определяет методы, которые безопасно выполняют приведение для вас:

    // Forward declarations.
class CFoo;
class CBar;

class CommonBase
{
public:
    virtual CFoo* GetFoo( void ) { return NULL };
    virtual CBar* GetBar( void ) { return NULL };
};

class CFoo : public GenericBase, public CommonBase
{
    .
    .
public:
    CFoo* GetFoo( void ) { return this };
};

class CBar : public GenericBase, public CommonBase
{
    .
    .
public:
    CBar * GetBar( void ) { return this };
};

Теперь, учитывая указатель на объект CommonBase, можно уменьшить значение путем "visting":

CommonBase *p;
CFoo pFoo = p->GetFoo();
if( pFoo )
{
    // Winner!
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...