跳到内容

更多 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

[编辑 | 编辑源代码]

参考文献

[编辑 | 编辑源代码]
华夏公益教科书