如何只在堆上gta5无非创建新的堆栈对象,如何只在栈上gta5无非创建新的堆栈对象

如何创建一个类只能在堆(栈)上建立对象 - 博客频道 - CSDN.NET
z_xiao_xue的博客
分类:c++数据结构
& 在C++中,类对象的建立方式有两种,一种是静态建立类对象,如A另一种是动态建立类对象,如A* p = new A;
这两种方式是有区别的:
& & 静态建立类对象:是指全局对象,静态对象,以及分配在栈区域内的对象,编译器对它们的内存分配是在编译阶段就完成的,是通过直接移动栈顶指针,挪出适当的空间,然后在这片内存空间上调用构造函数形成一个栈对象。使用这种方法,直接调用类的构造函数。
& & 动态建立类对象:分配堆区域内的对象,编译器对他们的内存分配是在运行时动态分配的,(使用new运算符将对象建立在堆空间中。这个过程分为两步,第一步,执行operator new()函数,在对中搜索合适的内存并进行分配,第二步,调用构造函数构造对象,初始化这片内存空间。使用这种方法,间接调用类的构造函数。
知道了这些,那么,如何限制类只能在堆上或栈上建立对象呢?
1.只能在堆上建立对象 &
& & 类对象只能建立在堆上,就是不能静态建立对象,即不能直接调用类的构造函数。
& & 很容易就想到把类的构造函数声明为私有,就无法在类的外部调用类的构造函数建立对象,只能使用new运算符来建立对象。前面已经说过,new运算符的执行过程分为两步,C++提供new运算符的重载其实只是允许重载operator new()函数,不能重载new运算符,而operator new()函数只用于分配内存,无法提供构造函数,所以,我们再定义一个GetObj函数,用于在堆上new对象,通过GetObj函数,建立的对象都是在堆上的new出来的,将函数声明为静态的,就可以通过域作用访问符访问GetObj函数,在堆上建立对象。(在C++中静态成员函数也是类函数,及这个函数不属于某个具体的对象,而是属于一个类的,这个类实例化的每个成员都可用,同时,这个类也可以直接调用这个函数而不用实例化一个对象。)&span style=&font-family:SimSfont-size:18&&class BB
static BB& GetObj(int b1 = 0,int b2 = 0)
return *(new BB(b1,b2));
BB(int b1 = 0,int b2 = 0)
void Test()
BB b = BB::GetObj();
网上还有一种说法,就是将析构函数声明为私有的,当对象建立在栈上面的时候,是由编译器分配内存空间
的,调用构造函数来构造栈对象,当对象使用使用完之后编译器会调用析构函数来释放栈对象,编译器管理了对象的
整个生命周期,如果编译器无法调用析构函数来释放空间,那会发生什么情况呢?比如,类的析构函数是私有的,编
译器无法调用析构函数来释放内存。所以,编译器在为类对象分配栈空间的时候,会先检查类的析构函数的访问性,
不只是析构函数,只要是非静态的函数,编译器都会检查,如果类的析构函数是私有的,那么编译器就不会在栈上位
类对象分配内存。
那么,到底为什么将析构函数声明为私有的就可以只在堆上建立对象呢?
因为c++是一个静态绑定的语言,在编译过程中,所有的非虚函数都必须分析完成,即使是虚函数,也需检查可访问
性,因此,当在栈上生成对象是,对象会自动析构,也就是说析构函数必须可访问,而对上生成对象,由于析构是由
程序员控制,所以,就可以不用析构函数,而重新定义一个函数完成析构函数的功能,然后手动调用。
protected:
void Test()
AA* a = new AA;
那么怎么释放它呢?& 析构函数私有化的类的设计可以保证只能用new命令在堆(heap)中创建对象, 只能动态的去创建对象, 这样可以自由的控制对象的生命周期. 但是, 这样的类需要提供创建和撤销的公共接口.&
AA::void Destory()
&& 上述方法的一个缺点就是,无法解决继承问题。如果A作为其它类的基类,则析构函数通常要设为virtual,然后在子类重写,以实现多态。因此析构函数不能设为private。还好C++提供了第三种访问控制,protected。将析构函数设为protected可以有效解决这个问题,类外无法访问protected成员,子类则可以访问。
这就证明了,如果要创建一个只能在堆上建立对象的类,无论将它的构造函数声明成私有还是析构函数声明为保护都可以达到这样的目的,但是,如果将该类的构造函数或析构函数声明为保护,最好将另外一个也声明为保护,因为例如你用new创建一个对象,
却不是用delete去删除它, 而是要用destroy方法,很显然,这是一种很奇怪的使用方法,所以,如果将该类的构造函数或析构函数声明为保护,最好将另外一个也声明为保护。
2.只能在栈上建立对象的类
只有使用new运算符,对象才会建立在堆上,所以只要禁用new运算符就可以实现类对象只能建立在栈上,将operator
new()设为私有就可以了,一定要记得,重载了new就要重载delete
void* operator new(size_t)//重载operator new() ,注意函数返回值和参数都是固定的
void operator delete(void* ptr)//也要重载operator delete()
z_xiao_xue
排名:千里之外
(13)(14)(12)(3)(2)(6)主题 : oc能在栈上创建对象么?
级别: 新手上路
可可豆: 179 CB
威望: 179 点
在线时间: 123(时)
发自: Web Page
oc能在栈上创建对象么?&&&
CGRect
NSObject
NSArray
后两行都会报编译错误 Interface type cannot be statically allocated
莫非跟NSObject 挂了@interface NSObject &NSObject&有关系?
为什么c++可以做到类似的栈上创建对象???
哪个明白人个解释啊?
级别: 新手上路
UID: 192125
可可豆: 23 CB
威望: 5 点
在线时间: 223(时)
发自: Web Page
后两个都是对象,变量名前面要加*, NSObject *
级别: 新手上路
可可豆: 34 CB
威望: 34 点
在线时间: 150(时)
发自: Web Page
写法问题,这就好比,I OK,String a ;要写成String *a;
级别: 新手上路
可可豆: 179 CB
威望: 179 点
在线时间: 123(时)
发自: Web Page
我知道应该使用*。。。。但是栈上创建有什么不对么?CO这在c++里是可以的啊?
级别: 新手上路
UID: 206706
可可豆: 210 CB
威望: 96 点
在线时间: 82(时)
发自: Web Page
oc所有的对象都是用指针来表示
CGRect 不是对象 所以不用加 * &如果你要创建对象 必须像这样创建 NSArray *
而访问str的property则是要加. &不像C++那样是加-&
如&array.xxx
找点oc的资料好好看一看吧....
级别: 新手上路
可可豆: 179 CB
威望: 179 点
在线时间: 123(时)
发自: Web Page
囧。。。。楼上诸位都觉得我不懂oc。。。 其实不是这样的我就是好奇一下 为什么NSObject的子类对象为什么不能创建到栈上而之前c++可以做到。。。。求深层次的分析 比如语言特性 语言实现方式等因素谢谢。
级别: 新手上路
UID: 206706
可可豆: 210 CB
威望: 96 点
在线时间: 82(时)
发自: Web Page
这个是跟object-c的内存管理有关的,因为OC管理对象是用的是引用计数
级别: 新手上路
可可豆: 3 CB
威望: 3 点
在线时间: 1(时)
发自: Web Page
第一、oc是在c上构建的,所以c++可以创建栈对象oc也不一定能。
第二、cocoa foundation的对象创建的时候都是经过alloc开辟存储空间。而alloc是这样实现的
+ (id) alloc
{
int size = sizeof(struct obj_layout) + size_of_the_
struct obj_layout *p = (struct obj_layout *)calloc(1, size);
return (id)(p + 1);
(说明一下,这是在苹果舍弃了NSZone的使用后的实现,以前会用到zone来处理内存碎片的问题。)
可以看到,它实际上是把calloc()封装在里面了,也就是说都是在堆区创建对象的。这样一来,foundation没有给你留下创建栈对象的接口。
接下来是我的推测了。。。所以编译器在语法上就直接给类似于C++中创建栈对象的形式判编译错误。
级别: 新手上路
可可豆: 179 CB
威望: 179 点
在线时间: 123(时)
发自: Web Page
关注本帖(如果有新回复会站内信通知您)
苹果公司现任CEO是谁?2字 正确答案:库克
发帖、回帖都会得到可观的积分奖励。
按"Ctrl+Enter"直接提交
关注CocoaChina
关注微信 每日推荐
扫一扫 浏览移动版

我要回帖

更多关于 智能对象 堆栈模式 的文章

 

随机推荐