Внедрение зависимостей в C ++ - PullRequest
4 голосов
/ 30 июня 2009

Как я могу реализовать внедрение зависимости в C ++ явно, без использования фреймворков или рефлексии?

Я мог бы использовать фабрику для возврата auto_ptr или shared_ptr. Это хороший способ сделать это?

Ответы [ 3 ]

4 голосов
/ 30 июня 2009

Просто используйте shared_ptr для нужного вам сервиса и настройте его. E.g.:

class Engine;

class Car {
public:
    void setEngine(shared_ptr<Engine> p_engine) {
        this->m_engine = p_engine;
    }

    int onAcceleratorPedalStep(int p_gas_pedal_pressure) {
        this->m_engine->setFuelValveIntake(p_gas_pedal_pressure);
        int torque = this->m_engine->getTorque();
        int speed = ... //math to get the car speed from the engine torque
        return speed;
    }

protected:
    shared_ptr<Engine> m_engine;
}

// (now must create an engine and use setEngine when constructing a Car on a factory)

Избегайте использования auto_ptr, потому что вы не можете поделиться им через более чем один объект (он передает право собственности при назначении).

1 голос
/ 30 июня 2009

Внедрение зависимостей AFAIK просто означает, что существует интерфейс для компонента, необходимого для другого.

namespace ifc {
  struct service { 
    virtual ~service() {}
    virtual do_stuff(/*..*/) = 0;  
  };
} // ns ifc

class ServiceProviderA : public ifc::service 
{ 
public;
  do_stuff(/*..*/) { /*...*/ }
};

class ServiceProviderB : public ifc::service {/*...*/};

class Client
{
public;
  client(ifc::service*);
private:
  ifc::service* m_service;
}; 

Я могу только догадываться, но есть ли у вас вопрос, как управлять временем жизни введенного объекта?

0 голосов
/ 26 ноября 2009

Как насчет предположения, что право собственности на внедренный объект переходит к зависимому объекту. Это решит проблему времени жизни для композиции, избегая использования умных указателей. Но для сложных ситуаций, где право собственности имеет значение, умные указатели будут выбором.

class Car {
    public:
      Car(IEngine *pEngine) {
        m_pEngine = pEngine;
      }

      ...

      ~Car()
      {
         delete m_engine;
      }

    protected:
      IEngine *m_pEngine;
    }

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

...