"Modern C++ Design"为什么PrototypeFactoryUnit::GetPrototype必须调用DoGetPrototype?

In "Modern C++ Design" why does PrototypeFactoryUnit::GetPrototype have to call DoGetPrototype?

本文关键字:调用 DoGetPrototype GetPrototype Design 为什么 PrototypeFactoryUnit Modern C++      更新时间:2023-10-16

在Andrei Alexandrescu的《现代C++设计》一书中,为什么PrototypeFactoryUnit::GetPrototype必须调用友元函数DoGetPrototype?为什么它不能直接将传入的指针设置为原型本身呢?对PrototypeFactoryUnit::SetPrototypeDoSetPrototype函数也做了同样的事情。

一些上下文!

template <class, class Base>
class PrototypeFactoryUnit: public Base {
public:
  typedef typename Base::ProductList::Head AbstractProduct;
  friend void DoGetPrototype(const PrototypeFactoryUnit& me,
                             AbstractProduct*& pPrototype)
  {
    pPrototype = me.pPrototype_;
  }
  template <class U>
  void GetPrototype(U*& p) {
    return DoGetPrototype(*this, p);
  }
private:
  AbstractProduct* pPrototype_;
};

(尽管它确实给了我清理这件衣服上灰尘的机会…)

因为GetPrototype是模板,所以它可以用许多不同的类型实例化。然后,过载解决方案将发挥作用!

例如,我写了一个DoGetPrototype(...& me, DerivedProduct*& p),然后说:

DerivedProduct* p =0;
factory.GetPrototype(p);

然后,调用my过载。

因此,这是一个定制点:一个静态调度,类似于具有默认实现的virtual函数的运行时对应部分。

如果您只编写

void GetPrototype(AbstractProduct*& p)
    { p = pPrototype_; }

其中AbstractProductPrototypeFactoryUnit的模板参数,则只有专用于最后一个ConcreteFactoryTList类型的GetPrototype才可见。

这是因为ConcreteFactory为每个TList的类型线性地继承了PrototypeFactoryUnit的专门化,并且GetPrototype的所有以前版本都将按名称隐藏。