zoukankan      html  css  js  c++  java
  • 如何定一个只能在堆上或者只能在栈上定义的类

    C++中,对象的建立分为两种,一种是静态建立,如A a;另一种是动态建立,如 A *ptr=new A;

    静态建立:由编译器为对象在栈上分配内存,是通过直接移动栈顶指针,挪出适当的空间,然后在这片内存空间上调用构造函数形成一个栈对象,使用这种方法,直接调用类的构造函数

    动态建立:是通过new运算符将对象建立在堆空间中,这个过程分为两步,第一步是执行operator new()函数,在堆空间中搜索合适的内存并进行分配,第二步是调用构造函数构造对象,初始化这片内存空间,这种方法,间接调用类的构造函数

    接下来进行限制对象只能在那里建立?

    1.只能建立在堆上?

     就是不能静态的建立对象,即不能直接调用类的构造函数。

    分析:

    (1)我们容易想到将构造函数设为私有,在构造函数私有之后,无法在类外部调用构造函数来构造类对象,只能使用new运算符来建立对象,然而,前面已经说过,new运算符的执行过程分为两步,c++提供new运算符的重载,其实是只提供operator new() 函数,而operator()函数是进行内存分配的,无法提供构造功能,因此这种方法是不可以的

    (2)对象建立在栈上面时,是由编译器分配空间的,调用构造函数来构造栈对象,当对象使用完之后,编译器会调用析构函数来释放栈对象所占的空间,编译器管理了对象的整个生命周期,编译器为对象分配空间的时候,只要是非静态的函数都会检查,包括析构函数,但是此时析构函数不可访问,编译器无法调用类的析构函数来释放内存,那么编译器将无法在栈上为对象分配内存

    class a{
        public :
            a(){}
            void destory(){
                delete this;
            }
        private:
            ~a(){};
    }; 

       那可以尝试使用a  b;来建立对象,编译报错,提示析构函数无法访问,这样就只能使用new来创建对象,构造函数是共有的,可以直接调用,但是类中必须通过destory()函数来进行内存的释放,类对象使用完之后,必须调用destory()函数

       上述方法两个缺点:(1)无法解决继承问题,因为通常情况之下a作为基类,一般析构函数要设为vitual,然后子类重写,已实现多态,因此析构函数不能设为private,不过c++还有protected访问控制方式,将析构函数设置为protected,这样子类可以访问,但是类外无法访问。(2)使用不方便,不统一,因为你使用了new创造了对象,但是不能使用delete释放对象,必须使用destory函数,这种方式比较怪异,所以我们也可以将构造函数设置为protected,同时提供另一public static create()函数来进行替代new。这样  create()创建对象在堆上, destory()释放内存

    class a{
        public :
            static a* create(){
                return new a();
            }
            void destory(){
                delete this;
            }
        protected:
            a(){};
            ~a(){};
    }; 

    2.只能建立在栈上

       只有使用new操作符,才会使对象建立在堆上,因此只要禁用new操作符就可以了,所以我们将operator new()操作符设为保护或者私有就可以了

    class a{
        public :
            a(){};
            ~a(){};
        protected:
            void* operator new(size_t t){};  //重载new,注意参数以及返回值 
            void operator delete(void *ptr){};  //重载了new,就要重载delete 
            
    }; 
  • 相关阅读:
    hashlib模块
    sys模块
    random模块
    time模块
    生成器、迭代器
    装饰器
    函数相关内容
    集合相关操作
    springcloud(四):Eureka的配置详解
    springcloud(二):Eureka服务注册与发现
  • 原文地址:https://www.cnblogs.com/jijiji/p/4862220.html
Copyright © 2011-2022 走看看