2010-02-06 5 views
0

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

Проблема заключается в том, как создать конструкцию EnginePart. У меня есть два варианта, описанные ниже, и я не знаю, какой из них выбрать. Вариант 1 быстрее, потому что он не имеет виртуальной функции. Вариант 2 проще, если я хочу клонировать() объект, потому что без данных ему не нужна функция Clone().

Любые мысли? Может быть, есть третий вариант?

Вариант 1:


class Part; 

class EnginePart : public Part { 
    protected: Engine *engine 
    public: void SetEngine(Engine *e) {engine = e} 
}; 

class Clutch : public EnginePart { 
    // code that uses this->engine 
} 

Вариант 2:


class Part; 

class EnginePart : public Part { 
    public: virtual void SetEngine(Engine *e)=0; 
}; 

class Clutch : public EnginePart { 
    private: Engine *engine; 
    public: void SetEngine(Engine *e) { engine = e; } 
    // code that uses this->engine 
} 

(Обратите внимание, что текущая ситуация немного сложнее, я не могу использовать простое решение, как создание отдельный список для блоков двигателей)

Thanks

+0

Возможно, я должен немного уточнить. Это на самом деле гибрид графика и n-арного дерева, загружаемого с диска, а части создаются загрузчиком с использованием абстрактной фабрики. Верхним n частям нужны некоторые глобальные свойства (я использовал Engine как свойство примера), которые не содержатся в самом графике. Вот почему я не могу предоставить его в конструкторе, я должен «ввести» его потом. – Eric

ответ

0

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

Поскольку требуется не полный двигатель, я нашел третий путь:


class Part; 

class EngineSettings { 
    private: 
     Engine *engine 
     friend class Engine; 
     void SetEngine(Engine *e) {engine = e} 
    public: 
     Value* GetSomeValue(params) { return engine->GetSomeValue(params); } 
}; 

class Clutch : public Part, public EngineSettings { 
    // code that uses GetSomeValue(params) instead of engine->GetSomeValue(params) 
} 

Поскольку GetSomeValue() необходимо несколько Params, которые двигателя не может знать, не существует никакого способа, он может «впрыснуть» это значение, как указатель двигателя был введен в опции 1 и 2. (Ну .. если я также не предоставил виртуальный GetParams()).

Это скрывает двигатель от сцепления и дает мне только один способ его кодирования.

0

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

Вы по-прежнему нуждаетесь в методе клонирования независимо от того, хотите ли вы скопировать из указателя/ссылки на базу, поскольку вы должны разрешить производным классам (неизвестным на данный момент) копировать себя, включая данные о реализации, такие как vtable указатели. (Хотя, если вы придерживаетесь одного компилятора/реализации, вы можете использовать на нем ярлыки и просто переоценивать их каждый раз, когда хотите использовать другой компилятор или хотите обновить свой компилятор.)

Это избавляет от всех критерии, которые вы указали, так что вы вернулись к тому, чтобы не знать, как выбрать. Но это легко: выберите тот, который вам проще всего сделать. (То есть, я не могу сказать, основываясь на этом составленном примере, но я подозреваю, что это первый.)

Смежные вопросы