栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

《More Effective C++》技术篇——要求(或禁止)对象产生于heap之中

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

《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 

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 
#include 
#include 

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 addresses;
};

std::list 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(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;
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/384447.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号