C ++中的依赖注入

时间:2009-06-29 20:53:19

标签: c++ refactoring dependency-injection

如何在不使用框架或反射的情况下显式实现C ++中的依赖注入?

我可以使用工厂返回auto_ptr或shared_ptr。这是一个很好的方法吗?

3 个答案:

答案 0 :(得分:4)

只需将shared_ptr用于您需要的服务,并为其创建一个setter。 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 :(得分:1)

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;
}; 

我只能猜测,但你的问题是如何管理注入对象的生命周期?

答案 2 :(得分:0)

假设注入对象的所有权转移到依赖对象如何。这将解决组合的生命周期问题,避免使用智能指针。但是,对于所有权问题的复杂情况,智能指针将是您的选择。

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

      ...

      ~Car()
      {
         delete m_engine;
      }

    protected:
      IEngine *m_pEngine;
    }

对于dependet肯定比注入对象具有更少生命周期的情况,最好将注入对象作为参考传递。这将清楚地表明注入的对象不属于dependet对象。