请教:a 和 *(&a) 有什么区别,"delete a" 和 "delete []a"又有什么区别?
见题目,我上google都查不到相关的解释,麻烦您解答一下,说一下你的看法和观点,非常感谢!!!
[解决办法]
a 和 *(&a) 是等效的
"delete a " 和 "delete []a " 前者删除一个元素 后者删除一组元素
[解决办法]
"delete a " 和 "delete []a "
a = new A;
delete a;
...........
a = new A[10];
delete []a;
[解决办法]
a和*(&a)等价
delete a和delete [] a是有区别的
delete a释放a所指的内存,如果a是类对象,还会调用a的析构函数
delete [] a释放a所指数组的内存,如果a是类对象,分别调用每个数组元素a[i]的析构函数
[解决办法]
楼上的delete解释的很完美了
C++告诉我们在回收用 new 分配的单个对象的内存空间的时候用 delete,回收用 new[] 分配的一组对象的内存空间的时候用 delete[]。
关于 new[] 和 delete[],其中又分为两种情况:(1) 为基本数据类型分配和回收空间;(2) 为自定义类型分配和回收空间。
对于 (1),上面提供的程序已经证明了 delete[] 和 delete 是等同的。但是对于 (2),情况就发生了变化。请看下面的程序。
#include <iostream> ;using namespace std;class T {public: T() { cout < < "constructor " < < endl; } ~T() { cout < < "destructor " < < endl; }};int main(){ const int NUM = 3; T* p1 = new T[NUM]; cout < < hex < < p1 < < endl; // delete[] p1; delete p1; T* p2 = new T[NUM]; cout < < p2 < < endl; delete[] p2;}
大家可以自己运行这个程序,看一看 delete p1 和 delete[] p1 的不同结果,我就不在这里贴运行结果了。
从运行结果中我们可以看出,delete p1 在回收空间的过程中,只有 p1[0] 这个对象调用了析构函数,其它对象如 p1[1]、p1[2] 等都没有调用自身的析构函数,这就是问题的症结所在。如果用 delete[],则在回收空间之前所有对象都会首先调用自己的析构函数。
基本类型的对象没有析构函数,所以回收基本类型组成的数组空间用 delete 和 delete[] 都是应该可以的;但是对于类对象数组,只能用 delete[]。对于 new 的单个对象,只能用 delete 不能用 delete[] 回收空间。
所以一个简单的使用原则就是:new 和 delete、new[] 和 delete[] 对应使用。
[解决办法]
a 和 *(&a) 是等效的
"delete a " 和 "delete []a " 前者删除一个元素 后者删除一组元素
[解决办法]
a和*(&a)不一定等效啊~~operator&是可以重载的,尽管这不是好的做法。
[解决办法]
a 和 *(&a) 没有区别!
有如下代码可以演示证明:
int main()
{
long a = 7;//这是你的那个‘a '演示值;
long b = a;//以变量a提领,以演示 "a ":
cout < < "演示a: " < < b < < endl;//显示出 "演示a: 7 "!
long c = *(&a);//以地址提领与指针操作符的组合演示 "*(&a) ":
cout < < "演示*(&a): " < < c < < endl;//显示出 "演示*(&a): 7 "!
_PAUSE;//一个便于观察演示的宏。
return 0;
}//演示该程序足以令你看到第1个问题的解。
如果有如下类:
class Pig
{
public:
Pig(){};
};
那么在堆上创建1个Pig对象,例如:
Pig* _pig = new _pig;//实际调用的是void* operator new(size_t) throw(bad_alloc);
上述语句的实现细节是:
第一步: Pig* _pig = _new(sizeof(pig));//内存资源获取,长度是sizeof(pig);
第二步: if(_pig) _pig = Pig::Pig(_pig);//C++伪码:调用Pig的构造函数;
重要的是第一步,内存资源申领的长度是1个对象的sizeof运算值!
第二步中的C++伪码我们是看不到的,但这的确是真的,其中构造函数参数表中那个_pig即是对象的this指针。(见《Inside The C++ Object Model》page255)这就是new运算符的实现细节!
如果我们在堆上创建一个Pig数组,例如:
Pig* _pigs = new Pig[3];
//实际调用的是: void* operator new[](size_t) throw(bad_alloc);
上述语句的实现细节是:
代码由编译器处理成:
Pig* _pigs = vec_new(0,sizeof(Pig),3,&Pig::Pig,&Pig::~Pig);
上述vec_new()函数或其类似的东东存在于C++的库文件(C++ Runtime Library)中,它体现具体的编译器对数组的构建策略。
注意;重要的是第2及第3个参数指定了内存空间的申领长度是 sizeof(Pig)* 3,以此容纳3个Pig对象,在vec_new()中还会调用第4个参数指定的可能存在的构造函数!
到此,相信你已经看到了new与new[]的不同。
最终,我们会删除在堆上创建的Pig对象,归还单个的Pig对象所占有的堆空间,例如:
delete _pig;//这是C++程序员的责任,不愿意的话就改行去学习Java!
对于delete,C++出于效率的考虑,它断定_pig指针一定是指向单个的Pig对象,因此简单的释放_pig所指向之地址,长度为sizeof(Pig)的堆内存空间。
那么我们最终还会删除在堆上创建的由_pigs指向的Pig数组,那么我们怎样告诉编译器,_pigs指向的空间是3个Pig对象所组成的Pig数组呢?这就是delete[]中的 '[] '!
Stanley B.Lipman博士告诉我们: "寻找数组的维度给delete运算符的效率带来极大的影响,所以才导至这样的妥协:只有在中括号出现时,编译器才寻找数组的维度,否则它便假设只有单独一个对象要被删除。 "(见《Inside The C++ Object Model》page259)
这就是delete与delete[]的不同之处!
[解决办法]
a和*(&a)几乎没有区别,a和*(&a)几乎是等效的。
如果a是内建类型,那么a和*(&a)的确是等效的。
我说a和*(&a)可能不等效(尽管这是很极端的情况),是因为如果a是类,而该类重载了address-of操作符,那么&a就不一定返回a的真实地址,*(&a)也就和a不一定等效了。
例如:
template <class T> //载自《C++设计新思维》P170
class SmartPtr
{
public:
T** operator&()
{
return &pointee_;
}
...
};
如果a是SmartPtr <int> 类型,那么*(&a)则是int*类型。显然,a和*(&a)有区别,a和*(&a)不再等效了。
PS:重载address-of操作符是不是好的设计!
[解决办法]
a 和 *(&a) 有什么区别
============
等效。
* & 是一对反操作,类似 */, /一下再*一下,结果自然一样[理论上]。
"delete a " 和 "delete []a "又有什么区别
===================
delete a 释放一个元素空间
delete[] a 释放一组元素空间,这个组有多少个元素,由new分配时候确定
【该组长度信息的保存,根据 Allocator确定】
[解决办法]
a和*(&a)没有区别
delete a释放a所指的内存
delete [] a释放a所指数组的内存
[解决办法]
a 和 *(&a) 没有区别
delete a 删除一个元素 delete []a 删除一组元素(数组)
[解决办法]
a和*(&a)几乎没有区别,a和*(&a)几乎是等效的。
delete a 删除一个元素 delete []a 删除一组元素(数组)
[解决办法]
a 和 *(&a) 没有区别
----------------------
说有区别的人来了。。。。。
a可以认为是1个队形,但是 &a 你可以认为是取对象的地址,你也可以认为是引用。。。。
加上引用就不一样了吧。哈哈哈