关于c++:More-Effective-C技术篇要求或禁止对象产生于heap之中

  • 要求对象产生于heap中,意思是须要阻止clients不得应用new以外的办法产生对象。比拟好的办法就是将destructor定义为private,因为constructor的类型太多,所以依然将constructor定义为public。而后定义一个pseudo destructor来调用真正的destructor。示例如下:

    class HeapBasedObject {
    public:
      HeapBasedObject() {}
      void destroy() const { delete this; } // pseudo destructor
    
    private:
      ~HeapBasedObject() {}
    };
    
    int main()
    {
      //HeapBasedObject h;
      HeapBasedObject *ph = new HeapBasedObject;
      //delete ph;
      ph->destroy();
    }
  • 禁止对象产生于heap中,则是要让clients不能应用new办法来产生对象。办法就是将operator new和operator delete定义为private。示例如下:

    #include <stdlib.h>
    
    class NoHeapBasedObject {
    public:
      NoHeapBasedObject() {}
      ~NoHeapBasedObject() {}
    
    private:
      static void *operator new(size_t size) {}
      static void operator delete(void *ptr) {}
    };
    
    int main()
    {
      NoHeapBasedObject nh;
      static NoHeapBasedObject snh;
      //NoHeapBasedObject *pnh = new NoHeapBasedObject;
    }
  • 下例是实现的一个判断某个对象是否位于heap内的基类HeapTracked。

    #include <stdlib.h>
    #include <list>
    #include <iostream>
    
    class HeapTracked {
    public:
      class MissingAddress{}; //地址异样
      virtual ~HeapTracked() = 0;
    
      static void *operator new(size_t size);
      static void operator delete(void *ptr);
    
      bool isOnHeap() const;
    
    private:
      typedef const void* RawAddress;
      static std::list<RawAddress> addresses;
    };
    
    std::list<HeapTracked::RawAddress> HeapTracked::addresses;
    
    HeapTracked::~HeapTracked() {}
    
    void* HeapTracked::operator new(size_t size) {
      void* memPtr = ::operator new(size); // 获得内存。
      addresses.push_front(memPtr); // 将其地址置于list头部。
      return memPtr;
    }
    
    void HeapTracked::operator delete(void *ptr) {
      auto it = std::find(addresses.begin(), addresses.end(), ptr);
    
      if (it != addresses.end()) {
          addresses.erase(it);
          ::operator delete(ptr);
      } else {
          throw MissingAddress();
      }
    }
    
    bool HeapTracked::isOnHeap() const {
      auto rawAddress = dynamic_cast<const void*>(this);
    
      auto it = std::find(addresses.begin(), addresses.end(), rawAddress);
      
      return it != addresses.end();
    }
    
    class Object: public HeapTracked {
    public:
      Object() {}
      ~Object() {}
    };
    
    
    int main()
    {
      Object o1;
      Object* o2 = new Object;
      std::cout << "o1 isOnHeap = " << o1.isOnHeap() << std::endl;
      std::cout << "o2 isOnHeap = " << o2->isOnHeap() << std::endl;
    }

【腾讯云】轻量 2核2G4M,首年65元

阿里云限时活动-云数据库 RDS MySQL  1核2G配置 1.88/月 速抢

本文由乐趣区整理发布,转载请注明出处,谢谢。

您可能还喜欢...

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据