zoukankan      html  css  js  c++  java
  • C++中限制对象的申请

    最近阅读Mitsuba的架构,有一个挺有意思的设计,开始没看明白。

    下面,我把限制对象的申请分两个方面讲述:

    1.限制对象在堆/栈上申请;

    2.限制对象申请的个数。

    //所有的资料,都可以在《more effective c++》上找到


    有一个基类Object,它的析构函数是protected访问权限的。并且,所有继承Object的类,都需要实现一个自己的protected的析构函数。

    Mitsuba还特意解释了,这是为了防止在stack上构建Object的对象

    这是怎么回事呢?

    在栈上构建的对象有什么特点呢?首先,在定义对象的地方会自动构造,并在生命周期结束时自动析构。所以,只要让那些被隐式调用的构造动作和析构动作不合法,就可以了“

    采用protected的目的是为了能够让类能够正常的被继承。但是!要保持子类也不能在栈上申请对象,必须保持子类的析构函数也是protected/private(若是private子类不能被继承,更多信息查看 http://www.cnblogs.com/wangpei0522/p/4460425.html)

    我们把析构函数设为了不可访问的protected/private,直接调用delete操作符释放资源不会通过编译的!

    为此,我们必须增加一个成员函数,在成员函数中使用delete释放资源。因为在成员函数内部,类的成员变得总是可见,所以delete能够成功执行。(Mitsuba中通过智能指针的方式释放资源。非常巧妙的设计)

     与防止在stack上构建对象的设计所对应的方案是

    防止在heap上构建对象

    亲爱的朋友,你肯定能想到设置operator new()的访问权限设置为protected/private,是吧?

    可是有一个问题:

    class onlyStack{
    protected:
        void* operator new (size_t s)
        {
    
        }
        void operator delete(void* ptr)
        {
    
        }
    private:
        int base_data;
    };
    
    class sets{
    private:
        onlyStack s;
    };
    sets* sets_array = new sets[100];

    上面的代码中,sets_array的定义语句发生了如下过程:

    调用sets的operator new申请了一块heap上的内存,然后调用调用sets的构造函数,sets的构造函数再调用了onlyStack的构造函数。全程没有用到onlyStack的operator new。

    我们并没有很好的办法解决这个问题,详见《more effective C++》 #27条款

    ^.^


    限制对象的个数

    什么是限制对象的个数?

    首先,如果我们限制对象可申请的个数为0的时,也就等价于不能申请对象。

    每当产生一个对象,它的构造函数都会被调用,所以,如果我们声明它的构造函数为private,此对象便不能显示申请(这里的显示申请意味着,我们可以通过别的方式申请它,比如静态成员函数调用了构造函数,此成员函数就能申请此对象)。

    还有什么?是的,抽象类也不能申请对象。我们可以定义一个纯虚函数,此对象就成为抽象类,便不能申请对象。

    接下来,我们限制对象可申请的个数为1的时,也就是大名鼎鼎的单例模式。

    继续扩展,我们限制对象可申请的个数为k,k是大于1的正整数。注意,此时的语义和前面的两个不太一样。可申请个数为0和1,只会出现不能申请和每次申请都只会那唯一的一个对象。

    也就是说,当我们申请的对象个数大于k的时候,会出现错误,或者处理错误的行为,而不是返回已经存在的k个对象中的某一个。

    简单说明下原理,我们在类中增加一个计数的数据成员,每次构造函数被调用就加一,析构函数被调用就减一。如果构造函数发现当前的计数成员已经等于最大值k,跳转到处理错误的情况。

    在《more effective c++》的条款26有详细的讲解,但是,我觉得他讲得很繁琐,特别是考虑继承的情况。被继承后,应该要根据具体的应用环境来确定计数。

    记得借鉴的是,通过private继承一个base counting class,该class是一个template类,为每个需要计数的class生成一套代码。


    以上。

  • 相关阅读:
    MobaXterm
    记一次完整的java项目压力测试
    jvm调优
    好用的公共dns服务器推荐(免费)
    SpringBoot,Security4, redis共享session,分布式SESSION并发控制,同账号只能登录一次
    javaCV资料目录
    基于JavaCV技术实现RTMP推流和拉流功能
    Java线程池详解
    微服务实战SpringCloud之Feign简介及使用
    【DP专题】——洛谷P5144蜈蚣
  • 原文地址:https://www.cnblogs.com/wangpei0522/p/4542223.html
Copyright © 2011-2022 走看看