跳到內容

更多 C++ 習語/虛擬建構函式

來自 Wikibooks,開放世界中的開放書籍

虛擬建構函式

[編輯 | 編輯原始碼]

在不知道其具體型別的情況下建立物件的副本或新物件。

也稱為

[編輯 | 編輯原始碼]

初始化的工廠方法

在面向物件程式設計社群中,在類層次結構中多型呼叫成員函式的使用是眾所周知的。它是實現is-a(或更實際地說,behaves-as-a)關係的一種方法。有時,多型呼叫類層次結構的生命週期管理(建立、複製和銷燬)函式很有用。

C++ 本身使用虛擬解構函式支援物件的 多型銷燬。但缺少對物件建立和複製的等效支援。在 C++ 中,物件的建立始終需要在編譯時知道其型別。虛擬建構函式習語允許在 C++ 中多型建立和複製物件。

解決方案和示例程式碼

[編輯 | 編輯原始碼]

create() 成員函式用於建立和 clone() 成員函式用於複製構造的效果,如下所示。

class Employee 
{
  public:
    virtual ~Employee () {}                 // Native support for polymorphic destruction.
    virtual Employee * create () const = 0; // Virtual constructor (creation) 
    virtual Employee * clone () const = 0;  // Virtual constructor (copying) 
};
class Manager : public Employee     // "is-a" relationship
{
  public:
    Manager ();                     // Default constructor
    Manager (Manager const &);      // Copy constructor
    virtual ~Manager () {}                  // Destructor
    Manager * create () const       // Virtual constructor (creation) 
    {
      return new Manager();
    }
    Manager * clone () const        // Virtual constructor (copying) 
    {
      return new Manager (*this);
    }
};
class Programmer : public Employee { /* Very similar to the Manager class */ };
Employee * duplicate (Employee const & e)
{
   return e.clone();  // Using virtual constructor idiom.
}

Manager 類實現兩個純虛擬函式,並使用型別名稱 (Manager) 建立它們。duplicate 函式展示了虛擬建構函式習語的使用方式。它實際上不知道它在複製什麼。它只知道它在克隆一個 Employee。建立正確例項的責任被委託給派生類。因此,即使以 Employee 為根的類層次結構將來添加了更多子類,duplicate 函式也對修改關閉。

Manager 類的 clone 和 create 成員函式的返回型別不是 Employee,而是類本身。C++ 允許在型別方面具有這種靈活性,其中重寫函式的返回型別可以是基類中函式的派生型別。這種語言特性稱為協變返回型別。

為了正確處理資源所有權,應該對 clone() 和 create() 函式的返回型別使用資源返回習語,因為它們是工廠函式。如果使用,返回型別 (shared_ptr<Employee> 和 shared_ptr<Manager>) 將不再是協變返回型別,程式將無法編譯。在這種情況下,派生類中的虛擬建構函式應該返回與父類中相同的精確型別。

#include <tr1/memory>

class Employee
{
  public:
    typedef std::tr1::shared_ptr<Employee> Ptr;
    virtual ~Employee () {}                    // Native support for polymorphic destruction.
    virtual Ptr create () const = 0; // Virtual constructor (creation)
    virtual Ptr clone () const = 0;  // Virtual constructor (copying)
};
class Manager : public Employee     // "is-a" relationship
{
  public:
    Manager () {}                     // Default constructor
    Manager (Manager const &) {}      // Copy constructor
    virtual ~Manager () {}
    Ptr create () const       // Virtual constructor (creation)
    {
      return Ptr(new Manager());
    }
    Ptr clone () const        // Virtual constructor (copying)
    {
      return Ptr(new Manager (*this));
    }
};

已知用途

[編輯 | 編輯原始碼]

std::function

[編輯 | 編輯原始碼]

參考文獻

[編輯 | 編輯原始碼]
華夏公益教科書