C++只在栈或堆上实例化对象
来源:互联网 发布:学directx编程要多久 编辑:程序博客网 时间:2024/05/21 00:17
C++如何让类对象只能在堆(栈)上分配空间
一般情况下写一个类都是可以采用new在堆上分配空间,或直接采用 类名+对象名 的方式在栈上分配空间。但有时候,如果想让一个类只能在栈上或者堆上分配空间,又该怎么实现呢?
下面分别来介绍如何定义只能在栈上或堆上实例化的类。
注:
1.静态实例化对象 如 A a;的步骤为:先由编译器为对象在栈空间分配内存,移动栈顶指针,挪出适当的空间,然后在这个空间上调用构造函数形成一个对象,在对象使用完之后,调用析构函数回收内存,栈顶指针减一。
2.动态实例化对象:new操作符,第一步执行operator new()函数在堆上分配一个内存,然后调用构造函数初始化这片空间。
1.只能在栈上分配类对象
只有使用new运算符,对象才会建立在堆上,因此要禁用new运算符才能只在栈上分配空间。但new操作符是C++内建的,所以必须要先认清一个事实即:new operator总是先调用operator new,所以我们只要堆new操作符进行重载,并将它声明为private的,就能保证不能再使用new实例化对象,如:
class A{private: void* operator new(size_t t){} void operator delete(void* ptr){}public: A(); ~A();};
那么此时就不能再调用new操作符了。
2.只能在堆上实例化对象
容易想到的方法是将构造函数私有化,那么在类外就不能实例化对象,只能在类内提供一个共有函数使用new运算符返回一个对象,这也是典型的单例模式的由来,但在类外还是不能使用new操作符进行实例化。所以这种方法是行不通的。
所以考虑析构函数的私有化。因在栈上实例化对象之后,对象使用完毕之后自动调用析构函数,而new对象后,要手动调用delete函数才能执行对象的析构函数。
所以当析构函数被私有化之后,若在栈上实例化对象,编译器先会检查该对象的析构函数是否可用,如果不可用,则会报错。在堆上释放对象时,若不调用delete就不会发现析构函数不可访问。
这就会引发另外一个问题,使用new操作符在堆上实例化的对象要怎么析构呢?解决办法就是,在类中自定义一个公有函数用来销毁对象,该函数调用delete操作符,这样就可以使用该函数销毁对象而不是直接使用delete操作符了。
如:
class A{public: A(){} void destroy(){delete this;}private: ~A(){}};
在此,就可以使用new在堆上创建对象而使用destroy()析构对象了。
注意:采用这种方式后,类A不能用在继承体系当中。
若A为基类,那么其析构函数就是virtual的(保证内存完全释放),子类必须要能重写该析构函数,但子类根本无法访问他,这是其一。其二,即使子类能够重写析构函数,若B是继承自A的子类,且声明了一个B类的对象b,那么此时若析构B,基类A不能被正确释放,导致内存泄露。
- C++只在栈或堆上实例化对象
- 只在堆上或只在栈上定义对象
- 面试题:C++如何只在堆上或栈上生成对象
- C++ 如何让类对象只在堆或栈上创建
- 只在堆上对象和栈上对象
- C++只在堆上与栈上创建对象
- C/C++如何让类对象只在栈(堆)上分配空间?
- 只在堆、栈上生成对象的类
- 如何只在堆或者栈上分配类对象
- 如何只在堆或者栈上分配类对象
- 让一个类只在堆/栈上创建对象
- 对象只在堆上创建
- c++ 只在堆上创建对象
- 限制一个类对象只在堆上分配或者只在栈上分配
- 如何限制一个类对象只在堆上分配或者只在栈上分配?
- 如何限制一个类对象只在堆上分配或者只在栈上分配?
- 如何限制一个类对象只在堆上分配或者只在栈上分配?
- 如何限制一个类对象只在堆上分配或者只在栈上分配?
- JBOSS基本安装以及端口的修改
- 剑指Offer-11.数值的整数次方
- IAR 使用小技巧--持续更新
- 24.session聚合统计之重构实现思路与重构session聚合
- TensorFlow学习笔记(1)——conv2d函数的padding参数详解
- C++只在栈或堆上实例化对象
- Android6.0以上权限相关Util
- myeclipse2014如何添加源码反编译工具插件
- ZigBee 用IO口模拟I2C驱动程序
- nginx 中的 rewrite 和 try_files
- MyEclipse配置Tomcat7
- django入门笔记
- 图解插入排序--直接插入排序
- uva 275 Expanding Fractions