【问题标题】:c++ Can I use std::unique_ptr with dependency injection?c++ 我可以将 std::unique_ptr 与依赖注入一起使用吗?
【发布时间】:2011-11-01 19:39:15
【问题描述】:

我一直在使用原始指针进行依赖注入,因此我决定将我的代码转换为使用 shared_ptr。这可行,但我想知道是否可以使用 unique_ptr 代替?在下面的示例中,MyClass 将管理信用卡服务的生命周期。

class PaymentProcessor
{
    PaymentProcessor(?? creditCardService):
      :creditCardService_(creditCardService)
      {

      }

private:
   CreditCardService *creditCardService_;     
}

class MyClass
{ 
public:
   void DoIt()
   {
     creditCardService_.reset(new VisaCardService());
     PaymentProcessor pp(creditCardService_);
     pp.ProcessPayment();
   }

private:   
   std::unique_ptr<CreditCardService> creditCardService_;
}

你能否将 unique_ptr 传递给另一个类,而另一个类只是“使用”指针(不拥有它??)?如果是这样,这是一个好主意吗?PaymentProcessor 的构造函数中的参数类型应该是什么?

更新

在上面显示的示例中,我也可以在堆栈上创建一个VisaCardService 变量,并让PaymentProcessor 构造函数将其作为参考参数。这似乎是推荐的 C++ 实践。但是,如果在运行时才知道 creditCardService_ 的具体类型(例如,用户选择在运行时使用的特定信用卡服务),使用 std::unique_ptr 和引用是最佳解决方案吗?

【问题讨论】:

  • 调用唯一指针的get()成员函数。
  • 根据您的更新:是的,这将是 std::unique_ptr 的用例。但是在这种情况下,这个指针仍然不需要是类的成员变量,如果它只需要在DoIt 中。您可以将其设为本地 std::unique_ptr,并具有动态分配的存储空间。这样,由于std::unique_ptrs 智能销毁设施,对象会在您离开函数后立即销毁。
  • 我同意克里斯蒂安的观点。除非您想以某种方式在多次调用中缓存服务,否则您的 unique_ptr 应该具有尽可能小的范围——这里是 DoIt 的范围。
  • @BartoszMilewski:同意。实际上,在我的代码中,我需要跨多个调用的服务。在这里,我试图使示例保持较小。

标签: c++ dependency-injection c++11 unique-ptr


【解决方案1】:

你能把一个 unique_ptr 传递给另一个类所在的另一个类吗 只是“使用”指针(不拥有它??)?

在这种情况下,将指针更改为引用:

class PaymentProcessor
{
public:
    PaymentProcessor(CreditCardService & creditCardService_):
      :creditCardService_(creditCardService_)
      {
      }

private:
   CreditCardService &creditCardService_;     
};

   void DoIt()
   {
     creditCardService_.reset(new VisaCardService());
     PaymentProcessor pp(*creditCardService_);
     pp.ProcessPayment();
   }

如果你还想使用指针,那么你需要使用get方法:

class PaymentProcessor
{
public:
    PaymentProcessor(CreditCardService * creditCardService_):
      :creditCardService_(creditCardService_)
      {
      }
private:
   CreditCardService *creditCardService_;     
};

   void DoIt()
   {
     creditCardService_.reset(new VisaCardService());
     PaymentProcessor pp(creditCardService_.get());
     pp.ProcessPayment();
   }

【讨论】:

  • 我同意,参考解决方案更好,更清楚地表达了这里发生了什么。
  • 实际上,在当前设置中,您甚至不需要动态分配MyClasscreditCardService_,但我猜(或者更确切地说希望)真正的代码要复杂一些。
  • @User:不。您可以在DoIt 函数中将其声明为局部变量。 PaymenProcessor 仍然需要引用基类,并且它对方法的所有调用仍然是动态的。但是在DoIt 中,您根本不需要将unique_ptr 与您显示的代码一起使用。我希望您的真实代码更复杂。
  • @User 你可以在MyClass 中创建一个VisaCardService 成员变量(没有指针),或者更好的是,在DoIt 中创建一个本地VisaCardService 变量。请始终记住,这是 C++,可以(并且应该在可能的情况下)使用自动变量,并且多态性不一定意味着动态分配。 PaymentProcessor 采用指针(或更好的引用)这一事实并不意味着需要动态分配此存储。但是当然,如​​果实际代码比这更复杂,你可能仍然需要一个动态分配的对象。
  • @User 当然可以,只要PaymentProcessor 接受(并存储)引用或指针。
猜你喜欢
  • 2021-01-19
  • 2017-01-01
  • 2021-02-09
  • 1970-01-01
  • 1970-01-01
  • 2014-08-29
  • 1970-01-01
  • 2017-05-22
  • 2018-02-22
相关资源
最近更新 更多