zoukankan      html  css  js  c++  java
  • 禁止或强制使用堆分配---《C++必知必会》 条款34

    有时候,指明一些特定类的对象不应该被分配到堆(heap)上是个好主意。通常这是为了确保该对象的析构函数一定会得到调用。维护对象本身(body object)的引用计数的句柄对象(handle object)就属于这种对象。具有自动存储区的类的局部对象,其析构函数会被自动调用(exit 或abort发生的非正常的程序终止情况出外),具有静态存储区的对象依然(abort除外),而堆分配的对象则必须被显示的销毁。

    指明对象不应该被分配到堆上的方式之一,是将其内存分配定义为不合法:

    #include<iostream>
    class NoHeap{
    protected:
        void * operator new(size_t){return 0;}
        //size_t 参数将被自动初始化为NoHeap对象的大小(以字节为单位)。
        void  operator delete(void *){}
        //void * 参数被编译器自动设置为"将被delete的那个对象地址"
    private:
        void * operator new[](size_t){return 0;}
        void operator delete[](void *);
    };
    class OnHeap{
    private:
        ~OnHeap(){};
    public:
        void destory(){ delete this;}
        //同时要提供一个共有的销毁对象的方法(例如:destroy),否则创建的对象将无从销毁
    };

    int main(int argc, char* argv[])
    {
         NoHeap ok;

        NoHeap * nh = new NoHeap;//错误!
        delete nh;//错误!
        
        OnHeap oh1; //错误!隐式调用私有析构函数

        OnHeap *oh2 = new OnHeap; //正确!
        oh2->destory(); //正确!
        return 0;
    }

    任何在堆上分配一个NoHeap对象的习惯性尝试,都将会导致编译期错误。

    之所以给出operator new 和 operator delete的定义(和声明),是因为在一些平台上他们可能会被构造函数和析构函数隐式调用。出于同样原因,我们将其声明为protected,因为它们可能会被派生类的构造函数和析构函数隐式调用。如果NoHeap不做基类,那么这两个函数也可以声明为private的。

    同时,还要注意阻止在堆上分配NoHeap对象的数组。在这种情况下,只要将 array new 和 array delete声明为private且不予以定义即可,类似于禁止复制操作的方式。

    当然,在某些场合下,我们可能鼓励而非阻止使用堆分配,为此,只需将析构函数声明为private即可。当对象的名字离开作用域时,任何一个声明或静态OnHeap对象的尝试,都将会导致一个隐式析构函数的调用,将发生错误。

  • 相关阅读:
    线性滤波器(linear filter)与非线性滤波器(non-linear filter)
    线性滤波器(linear filter)与非线性滤波器(non-linear filter)
    80后开网店卖故事:1500多位为感觉而埋单
    [置顶] think in java interview-高级开发人员面试宝典(一)
    Android ToggleButton Example--开关按钮
    UVA 10012 How Big Is It?(暴力枚举)
    Windows远程连接的实现
    系统集成项目管理之项目采购管理
    UVA 165 Stamps (DFS深搜回溯)
    EF操作增删改查
  • 原文地址:https://www.cnblogs.com/azbane/p/8610878.html
Copyright © 2011-2022 走看看