初始化期間呼叫虛函數 (Calling Virtuals During Initialization)

動機

``` class Base {
public:
Base();
...
virtual void foo(int n) const; // 經常為純虛函數
virtual double bar() const;    // 經常為純虛函數
};

Base::Base()
{
... foo(42) ... bar() ...
// 這裡將不會使用動態綁定
// 目的： 藉由呼叫這些虛函數模擬動態綁定
}

class Derived : public Base {
public:
...
virtual void foo(int n) const;
virtual double bar() const;
};
```

解決方案與範例程式

```class Base {
public:
void init();  // 有可能是或不是虛函數
...
virtual void foo(int n) const; // 經常為純虛函數
virtual double bar() const;    // 經常為純虛函數
};

void Base::init()
{
... foo(42) ... bar() ...
// 大部分這些從原始的 Base::Base()被複製
}

class Derived : public Base {
public:
Derived (const char *);
virtual void foo(int n) const;
virtual double bar() const;
};
```
• 使用非成員函數
```template <class Derived, class Parameter>
std::auto_ptr <Base> factory (Parameter p)
{
std::auto_ptr <Base> ptr (new Derived (p));
p->init ();
return p;
}
```

```class Base {
public:
template <class D, class Parameter>
static std::auto_ptr <Base> Create (Parameter p)
{
std::auto_ptr <Base> ptr (new D (p));
p->init ();
return p;
}
};
int main ()
{
std::auto_ptr <Base> b = Base::Create <Derived> ("para");
}
```

• 不使用二階段初使化

```class Base {
};
template <class D>
class InitTimeCaller : public Base {
protected:
InitTimeCaller () {
D::foo ();
D::bar ();
}
};
class Derived : public InitTimeCaller <Derived>
{
public:
Derived () : InitTimeCaller <Derived> () {
cout << "Derived::Derived()\n";
}
static void foo () {
cout << "Derived::foo()\n";
}
static void bar () {
cout << "Derived::bar()\n";
}
};
```