在Andrei Alexandrescu的书“现代C++设计”中,为什么PrototypeFactoryUnit::GetPrototype必须调用 friend 函数DoGetPrototype?为什么不能仅将传入的指针设置为原型(prototype)本身? 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);

然后,我的重载被调用。

因此,这是自定义的要点:与默认实现类似的静态分发等效于virtual函数的运行时对应项。

07-24 14:07