跳至内容

更多 C++ 习语/具体数据类型

来自维基教科书,开放的书籍,开放的世界

具体数据类型

[编辑 | 编辑源代码]

通过允许或禁止使用自由存储(堆)进行动态分配来控制对象的范围和生命周期

也称为

[编辑 | 编辑源代码]

C++ 提供了两种方法来控制对象的生存期并将其绑定到程序级标识符(变量)。第一种是作用域变量和对象,它们在作用域结束后立即被销毁(例如,函数作用域中的整数)。第二种是作用域变量(通常是指针)和自由存储中动态分配的对象。在这种情况下,在变量作用域结束时,变量将不再存在,但对象的生存期将继续(例如,单例、窗口对象)。可以使用具体数据类型习语强制选择对象生存期的第一种方式或第二种方式。

解决方案和示例代码

[编辑 | 编辑源代码]

此习语简单地使用类级访问修饰符(private、protected)来实现目标。以下代码展示了 MouseEventHandler 类如何强制动态分配。

class EventHandler 
{
  public:
    virtual ~EventHandler () {}
};
class MouseEventHandler : public EventHandler // Note inheritance
{
  protected:
    ~MouseEventHandler () {} // A protected virtual destructor.
  public:
    MouseEventHandler () {} // Public Constructor.
};
int main (void)
{
  MouseEventHandler m; // A scoped variable is not allowed as destructor is protected.
  EventHandler *e = new MouseEventHandler (); // Dynamic allocation is allowed
  delete e;  // Polymorphic delete. Does not leak memory.
}

强制动态分配的另一种方法是阻止对构造函数的直接访问,而是提供一个静态函数 instance() 来返回一个动态分配的对象。它在许多方面类似于单例设计模式。此外,严格来说,使用多态删除来回收内存并不是必需的。一个成员函数 destroy() 可以达到这个目的,从而节省了用于 v-table 指针的空间。

class MouseEventHandler // Note no inheritance
{
  protected:
    MouseEventHandler () {} // Protected Constructor.
    ~MouseEventHandler () {} // A protected, non-virtual destructor.
  public:
    static MouseEventHandler * instance () { return new MouseEventHandler(); }
    void destroy () { delete this; }  // Reclaim memory.
};

此习语的另一个极端是强制使用作用域变量(又称自动变量)。这可以通过使用私有 new 运算符来实现。

class ScopedLock
{
  private:
    static void * operator new (size_t size); // Disallow dynamic allocation
    static void * operator new (size_t, void * mem);  // Disallow placement new as well.
};
int main (void)
{
   ScopedLock s; // Allowed
   ScopedLock * sl = new ScopedLock (); // Standard new and nothrow new are not allowed.
   void * buf = ::operator new (sizeof (ScopedLock));
   ScopedLock * s2 = new(buf) ScopedLock;  // Placement new is also not allowed
}

ScopedLock 对象不能使用 new 运算符、nothrow new 运算符和 placement new 运算符进行动态分配。

已知用途

[编辑 | 编辑源代码]
[编辑 | 编辑源代码]

参考文献

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