简体   繁体   English

如何改善实例化此对象的方式?

[英]How can I improve how this object is instantiated?

Consider this "design" (implementation details left out): 考虑一下这个“设计”(省略了实现细节):

struct service {};

struct sub {
  sub(service&) {}
  service& s_;
};

struct sub_a: sub {
  sub_a(service&) {}
};

struct sub_b: sub {
  sub_b(service&) {}
};

struct top {
  service svc_;
  sub_ptr sub_;
};

Basically, my top object holds sub_ptr , but the instance held by this pointer requires access to svc_ in order to be instantiated, which is also in top . 基本上,我的top对象包含sub_ptr ,但是此指针所保存的实例需要访问svc_才能实例化,该实例也在top However, I want a user of top to be able to choose the type of sub (here sub_a or sub_b ), without giving access to svc_ . 但是,我希望top用户能够选择sub的类型(此处为sub_asub_b ),而无需授予对svc_访问svc_

My solution so far is to have my constructor of top like this: 到目前为止,我的解决方案是让我的top构造函数像这样:

template <typename SubType>
top(std::unique_ptr<SubType>): sub_(new SubType(svc_)) {}

Here is the usage: 用法如下:

auto t = top(std::unique_ptr<sub_b>());

But I don't feel like this solution is elegant. 但是我不觉得这种解决方案是优雅的。 I could write functions (eg. make_top_sub_b() ) to hide the details, but I was wondering how I could avoid giving a dummy pointer to my constructor? 我可以编写函数(例如make_top_sub_b() )来隐藏细节,但是我想知道如何避免向构造函数提供虚拟指针? Making top a templated class is not an option. 使模板类成为top不是一个选择。

Any idea how I could improve this? 知道我该如何改善吗? Thanks, 谢谢,

The Liskov substitution principle would hear suggest that users of sub_ptr would not need to be aware of which implementation it held. Liskov替换原则将表明, sub_ptr 用户不需要知道它持有哪种实现。

As sub_ptr is wrapped within top , you can say that top is a user. 由于sub_ptr包装在top ,因此可以说top是用户。

The construction of the sub needs to be done via its factory and the service it references must have a lifetime that is longer than that of the class that holds the reference. sub的构造需要通过其工厂来完成,并且其引用的service的寿命必须比保存引用的类的寿命更长。

In your case the lifetime of the service object appears to be in top which means the sub must have a shorter lifetime. 在您的情况下,服务对象的生存期似乎在top ,这意味着该sub的生存期必须较短。

You could have a sub_factory class that is abstract and creates one from a service. 您可能拥有一个抽象的sub_factory类,并从服务中创建了一个。

eg 例如

struct sub_factory
{
   virtual sub* create( service_ & ) const = 0;
};


struct sub_a_factory : sub_factory 
{ 
       // detail, creates sub_a
};

struct sub_b_factory : sub_factory
{
     // detail, creates sub_b
};

top::top( sub_factory const & fact ) :
      sub_( fact.create( svc_ ) )
{
}

sub_factory_a afact;
sub_Factory_b bfact;
top ta(  afact );
top tb( bfact );

Note that you can use the initialiser list here as svc_ appears above sub_ in your class so gets initialised first. 请注意,您可以在此处使用初始化程序列表,因为svc_出现在类中的sub_上方,因此需要首先进行初始化。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM