请教:a 和 *(&a) 有什么区别,"delete a" 和 "delete []a"又有什么区别?

请教:a 和 *(&a) 有什么区别,"delete a" 和 "delete []a"又有什么区别? [已结贴,结贴人:yaoike]
进入用户个人空间
加为好友
发送私信
在线聊天
  • yaoike
  • 等级:
  • 可用分等级:
  • 总技术分:
  • 总技术分排名:
  • 揭贴率:
发表于:2007-08-23 17:56:20 楼主
见题目,我上google都查不到相关的解释,麻烦您解答一下,说一下你的看法和观点,非常感谢!!!
70  修改 删除 举报 引用 回复
进入用户个人空间
加为好友
发送私信
在线聊天
  • Microsoft777
  • 等级:
  • 可用分等级:
  • 总技术分:
  • 总技术分排名:
发表于:2007-08-23 18:00:491楼 得分:5
a   和   *(&a)   是等效的
"delete   a "   和   "delete   []a "   前者删除一个元素   后者删除一组元素
修改 删除 举报 引用 回复
进入用户个人空间
加为好友
发送私信
在线聊天
  • hoya5121
  • 等级:
  • 可用分等级:
  • 总技术分:
  • 总技术分排名:
发表于:2007-08-23 18:00:542楼 得分:5
"delete   a "   和   "delete   []a "

a   =   new   A;
delete   a;
...........

a   =   new   A[10];
delete   []a;
修改 删除 举报 引用 回复
进入用户个人空间
加为好友
发送私信
在线聊天
  • gfxiang
  • 等级:
  • 可用分等级:
  • 总技术分:
  • 总技术分排名:
发表于:2007-08-23 18:14:003楼 得分:5
a和*(&a)等价

delete   a和delete   []   a是有区别的
delete   a释放a所指的内存,如果a是类对象,还会调用a的析构函数
delete   []   a释放a所指数组的内存,如果a是类对象,分别调用每个数组元素a[i]的析构函数
修改 删除 举报 引用 回复
进入用户个人空间
加为好友
发送私信
在线聊天
  • fmjk525283
  • 等级:
  • 可用分等级:
  • 总技术分:
  • 总技术分排名:
发表于:2007-08-23 18:25:574楼 得分:10
楼上的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[]   对应使用。
修改 删除 举报 引用 回复
进入用户个人空间
加为好友
发送私信
在线聊天
  • wpp_zyt
  • 等级:
  • 可用分等级:
  • 总技术分:
  • 总技术分排名:
发表于:2007-08-23 18:46:575楼 得分:5
a   和   *(&a)   是等效的
"delete   a "   和   "delete   []a "   前者删除一个元素   后者删除一组元素

修改 删除 举报 引用 回复
进入用户个人空间
加为好友
发送私信
在线聊天
  • iatsbg
  • 等级:
  • 可用分等级:
  • 总技术分:
  • 总技术分排名:
发表于:2007-08-23 19:21:266楼 得分:5
a和*(&a)不一定等效啊~~operator&是可以重载的,尽管这不是好的做法。
修改 删除 举报 引用 回复
进入用户个人空间
加为好友
发送私信
在线聊天
  • fish6344
  • 等级:
  • 可用分等级:
  • 总技术分:
  • 总技术分排名:
发表于:2007-08-23 23:46:237楼 得分:10
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[]的不同之处!


修改 删除 举报 引用 回复
进入用户个人空间
加为好友
发送私信
在线聊天
  • iatsbg
  • 等级:
  • 可用分等级:
  • 总技术分:
  • 总技术分排名:
发表于:2007-08-24 01:03:478楼 得分:8
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操作符是不是好的设计!
修改 删除 举报 引用 回复
进入用户个人空间
加为好友
发送私信
在线聊天
  • jixingzhong
  • 等级:
  • 可用分等级:
  • 总技术分:
  • 总技术分排名:
  • 2

    17

    2

发表于:2007-08-24 07:47:469楼 得分:5
a   和   *(&a)   有什么区别
============
等效。
*     &   是一对反操作,类似   */,   /一下再*一下,结果自然一样[理论上]。

"delete   a "   和   "delete   []a "又有什么区别
===================
delete   a         释放一个元素空间
delete[]   a     释放一组元素空间,这个组有多少个元素,由new分配时候确定
【该组长度信息的保存,根据   Allocator确定】
修改 删除 举报 引用 回复
进入用户个人空间
加为好友
发送私信
在线聊天
  • farmerice
  • 等级:
  • 可用分等级:
  • 总技术分:
  • 总技术分排名:
发表于:2007-08-24 08:40:2310楼 得分:0
fish6344()   (   )   信誉:100
写的很认真哦...谢谢呢,呵呵~就是言辞犀利了些~大家讨论嘛...嘿嘿
修改 删除 举报 引用 回复
进入用户个人空间
加为好友
发送私信
在线聊天
  • scrutin
  • 等级:
  • 可用分等级:
  • 总技术分:
  • 总技术分排名:
发表于:2007-08-24 08:46:4211楼 得分:0
大家讨论得挺好     我就进来接分了     ^_^
修改 删除 举报 引用 回复
进入用户个人空间
加为好友
发送私信
在线聊天
  • jhs1982419
  • 等级:
  • 可用分等级:
  • 总技术分:
  • 总技术分排名:
发表于:2007-08-24 10:06:0912楼 得分:3
a和*(&a)没有区别


delete   a释放a所指的内存


delete   []   a释放a所指数组的内存
修改 删除 举报 引用 回复
进入用户个人空间
加为好友
发送私信
在线聊天
  • lfcai
  • 等级:
  • 可用分等级:
  • 总技术分:
  • 总技术分排名:
发表于:2007-08-24 12:09:3913楼 得分:3
a   和   *(&a)   没有区别

delete   a   删除一个元素   delete   []a   删除一组元素(数组)
修改 删除 举报 引用 回复
进入用户个人空间
加为好友
发送私信
在线聊天
  • higter
  • 等级:
  • 可用分等级:
  • 总技术分:
  • 总技术分排名:
发表于:2007-08-24 12:14:2114楼 得分:0
哇,这么多人回答?
修改 删除 举报 引用 回复
进入用户个人空间
加为好友
发送私信
在线聊天
  • lkldiy
  • 等级:
  • 可用分等级:
  • 总技术分:
  • 总技术分排名:
发表于:2007-08-24 12:44:2515楼 得分:0
没什么说的了
修改 删除 举报 引用 回复
进入用户个人空间
加为好友
发送私信
在线聊天
  • yc_8301
  • 等级:
  • 可用分等级:
  • 总技术分:
  • 总技术分排名:
发表于:2007-08-24 12:54:0616楼 得分:0
都说完了,支持一下。。
修改 删除 举报 引用 回复
进入用户个人空间
加为好友
发送私信
在线聊天
  • charlen
  • 等级:
  • 可用分等级:
  • 总技术分:
  • 总技术分排名:
发表于:2007-08-24 12:58:2217楼 得分:0
fish6344   正解~
修改 删除 举报 引用 回复
进入用户个人空间
加为好友
发送私信
在线聊天
  • tncqsy
  • 等级:
  • 可用分等级:
  • 总技术分:
  • 总技术分排名:
发表于:2007-08-24 14:02:2218楼 得分:0
同意:iatsbg()   (   )   的
修改 删除 举报 引用 回复
进入用户个人空间
加为好友
发送私信
在线聊天
  • Nowish
  • 等级:
  • 可用分等级:
  • 总技术分:
  • 总技术分排名:
发表于:2007-08-24 14:26:5219楼 得分:0
o
修改 删除 举报 引用 回复
进入用户个人空间
加为好友
发送私信
在线聊天
  • zkcq2004
  • 等级:
  • 可用分等级:
  • 总技术分:
  • 总技术分排名:
发表于:2007-08-24 15:16:5220楼 得分:3
a和*(&a)几乎没有区别,a和*(&a)几乎是等效的。

delete   a   删除一个元素   delete   []a   删除一组元素(数组)
修改 删除 举报 引用 回复
进入用户个人空间
加为好友
发送私信
在线聊天
  • bsnail
  • 等级:
  • 可用分等级:
  • 总技术分:
  • 总技术分排名:
发表于:2007-08-24 15:45:3821楼 得分:0
都说完了
留个脚印吧
修改 删除 举报 引用 回复
进入用户个人空间
加为好友
发送私信
在线聊天
  • langkefeixia
  • 等级:
  • 可用分等级:
  • 总技术分:
  • 总技术分排名:
发表于:2007-08-24 15:59:0522楼 得分:0
学习了
修改 删除 举报 引用 回复
进入用户个人空间
加为好友
发送私信
在线聊天
  • expter
  • 等级:
  • 可用分等级:
  • 总技术分:
  • 总技术分排名:
发表于:2007-08-24 16:14:5523楼 得分:0
up
修改 删除 举报 引用 回复
进入用户个人空间
加为好友
发送私信
在线聊天
  • xxyyboy
  • 等级:
  • 可用分等级:
  • 总技术分:
  • 总技术分排名:
发表于:2007-08-24 16:42:5624楼 得分:3
a   和   *(&a)   没有区别
----------------------
说有区别的人来了。。。。。
a可以认为是1个队形,但是   &a   你可以认为是取对象的地址,你也可以认为是引用。。。。
加上引用就不一样了吧。哈哈哈
修改 删除 举报 引用 回复
进入用户个人空间
加为好友
发送私信
在线聊天
  • fish6344
  • 等级:
  • 可用分等级:
  • 总技术分:
  • 总技术分排名:
发表于:2007-08-26 19:58:0325楼 得分:0
farmerice()朋友批评得是,但我来CSDN论坛是想和大家共同研讨,共同受益!再次向朋友们致意,绝没有贬谁的意思,语言有时率直一些,请朋友们一定海涵,谢谢!
修改 删除 举报 引用 回复
进入用户个人空间
加为好友
发送私信
在线聊天
  • fish6344
  • 等级:
  • 可用分等级:
  • 总技术分:
  • 总技术分排名:
发表于:2007-08-26 21:16:1826楼 得分:0
iatsbg()朋友提出的 "a如果是自定义类型,且又重载了 '& '运算符, "则 "a和*(&a)可能不等效 "的情况,我想和大家讨论如下:

              从技术上说,自定义类型类重载的运算符,可以随心所欲,例如有如下类:

class   A
{
mutable   long   a;
public:
A(){   a   =   7;}
long   operator++(void)   const//一个改变运算符语义的重载!
{
        return   --a;
}
void   show(void)
                  {  
                        cout   < <   "a:   "   < <   a   < <   endl;
                  }
};

你可以看到:

int   main()
{
        A   _a;
        _a.show();//这将显示A成员a的初始值为7!

        ++_a;
        _a.show();//这将显示A成员a的--结果为6!

        _PAUSE;
        return   0;

}

上述重载的 '++ '运算符,已经改变了内建 '++ '运算符的语义!

iatsbg()朋友提出的问题与此类似,主要是担心 '& '经重载后,改变了内建 '& '运算符的语义。如此一来,当然 "a和*(&a)可能不等效 "。

          我想说的是,上述重载的行为,是一个C++程序员不应有的重载!虽然技术可行,但却违背了语言对重载运算符支持的初衷!C++因为对重载运算符提供支持,使我们的自定义类型也象内建类型一样支持内建运算符的语言高阶特性,隐藏运算符实现的底层实现。一句话,无论 '& '运算符重载的底层实现如何,程序员有责任维护 '& '运算符的高阶语意-那就是地址提取!进一步推论:就是要保证 "a和*(&a)等效 "!

            所以对于可能的正确的重载 "& "运算符,a和*(&a)同样等效!


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值