社区
C++ 语言
帖子详情
delete的问题
fixopen
2004-08-26 06:26:55
T* o = new T();
void* p = o;
.....
delete p; //what do the delete do?
他能知道p的类型么?怎么能够调用T的析构函数?
...全文
713
63
打赏
收藏
delete的问题
T* o = new T(); void* p = o; ..... delete p; //what do the delete do? 他能知道p的类型么?怎么能够调用T的析构函数?
复制链接
扫一扫
分享
转发到动态
举报
AI
作业
写回复
配置赞助广告
用AI写文章
63 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
fixopen
2004-09-13
打赏
举报
回复
我觉得现在有两个问题需要明确:
1.类型转换时究竟干了什么?他又分成这么几个子问题(我下面的叙述都省略了指针)
a从子类道父类的转换,子类和父类都没有虚函数
b从子类道父类的转换,子类有虚函数,父类没有
c从子类道父类的转换,子类和父类都有虚函数
d没有关系的类间转换,都没有虚函数
e没有关系的类间转换,转换前有的类有虚函数,转换后的类没有虚函数
f没有关系的类间转换,转换前有的类没有虚函数,转换后的类有虚函数
g没有关系的类间转换,都有虚函数
h类转换成原始类型,类没有虚函数
i类转换成原始类型,类有虚函数
j原始类型转换成类,类没有虚函数
k原始类型转换成类,类有虚函数
2.delete xxx究竟干了什么?他又分成这么几个子问题(我下面的叙述都省略了指针)
a.xxx是类类型,且无虚析构
b.xxx是类类型,有虚析构
c.xxx是原始类型
fixopen
2004-09-13
打赏
举报
回复
to ljan(冰魂):
>delete (C*)o;
>若C的析构函数不是虚拟的,那么这样转型,实际告诉编译器把o指针指向的对象按C类型来处理,自然调用C的析构函数,按一般的成员函数来处理。
如果我理解的没错的话,你的意思是说:
T* o = new T();
C* p = (C*)o;
如果delete o,会演化成vptr->vtbl[T's virtual dtor offset],
而如果delete p,会演化成vptr->vtbl[C's virtual dtor offset]
是么?
但如果是这样的话,我认为不可能是在delete xxx的时候确定的,而只能是在类型转换的时候确定的,那就是说,类型转换会导致一定的动作,修改offset值。
to xteaj()
你说的有道理,这也是我前面担心的一个问题
〉哦,我看出可能的问题是什么了,可能的问题是void*的delete会跟free一样,也就是没有析构的调用,因为它毕竟是一个原始类型。
wgsspank
2004-09-13
打赏
举报
回复
我都晕了,呵呵,向高手学习!真是闻道有先后,术业有专攻!
一叶还真不知秋
2004-09-12
打赏
举报
回复
对于内建类型和类类型,C++在解构时应该是采用两种解构方式的。
对于内建类型,不需要析构过程,直接回收内存就可以了。
如int *p = new int;
delete p;直接回收4Bytes就可以了,不需要更多的处理。
对于类类型,有更多的信息需要处理,所以要比较具体的析构函数。
void是内建类型,采取直接回收内存,但void又是未知类型,无法知道
该释放多少内存,所以就会出问题。
slqit2002
2004-09-12
打赏
举报
回复
我认为c++对不同的指针类型采用了不同的处理方法
riffle
2004-09-12
打赏
举报
回复
用下面的代码似乎更好说明问题:
char *p = new char[ 1 ];
T* o = NULL;
o = ( T* )p;
delete o;
上面的代码拿来执行的话,机器多半会死的。
对于编译器,它只关心delete后面的“东西”是什么(类型),并从而产生相应的代码,而不会
关心那个指针真正指向的是什么。至于说拿基类指针指向子类,然后删除它,能调用正确的析构
函数,那是因为该基类的析构函数是虚函数,将被编译器纳入VTABLE中,所有派生类的析构函数
在VTABLE中的位置都一样,编译器对delete运算符产生的代码都是CALL VTABLE中的对应位置的
那个函数,自然能调用正确的析构函数了。
对于上面的代码,编译器“傻呼呼”地按照T类的析构函数规则去执行,不出问题那就奇怪了。
无论T类的析构造函数是否虚函数,都极可能会出异常。举一个例子,假设T类有一个成员变量
是char *m_p;在其析构函数里有一句delete m_p;想想看,上述代码才为p分配一个字节空
间哪,delete m_p会有什么后果呢?
myling
2004-09-12
打赏
举报
回复
感觉好多人都认为析构函数就是delete一样
jxhwei
2004-09-11
打赏
举报
回复
好搞笑,使用delete跟析构函数有什么关系?!delete单纯的跟new配对使用,你用new得到一段内存空间,那么delete就释放一段内存空间,才不管你new的是什么。
williamVII
2004-09-11
打赏
举报
回复
不能,无法调用析构函数。
ljan
2004-09-11
打赏
举报
回复
这个偏移量就是函数地址在虚函数表中的索引啦,编译时就已经确定好了的
对应T,T',他们的虚拟析构函数,在虚函数表的索引是一样的,只不过在派生类T'的虚函数表中,相同索引位置放的是T' 的析构函数指针而已。
delete (C*)o;
若C的析构函数不是虚拟的,那么这样转型,实际告诉编译器把o指针指向的对象按C类型来处理,自然调用C的析构函数,按一般的成员函数来处理。
若C的析构函数为虚拟函数,假设T的析构函数在虚表中索引为1,那么实际编译器处理为
o->vptr[1],调用的仍为T'的析构函数
Tranum
2004-09-10
打赏
举报
回复
mark
xiao_wang
2004-09-10
打赏
举报
回复
T* o = new T'();
delete (T*)o; //T' dtor
如果这个不出问题的话,有理由认为
T* o = new T'();
delete (C*)o;
会出问题?
当然,我说的都是他们的dtor是虚的。
------------------------------------------------------------------------
我想如果C是T'的父类,那么不会出问题,否则发生错误!
wwwooowww
2004-09-10
打赏
举报
回复
向高手致敬!!!!!
学习!!!!!!!!
fixopen
2004-09-10
打赏
举报
回复
to steedhorse(晨星)
现在的问题的关键是,进行类型转换时,会不会修改其offset值?我觉得好象没有必要。
比如:最常见的父子类转换,应该根本没有必要修改offset值,如果能够向无关的类类进行转换,那么编译器有责任保证还调用到相应的virtual dtor,也就是说,既然它允许,就要保证安全,那么他应该也不会修改offset,你觉得呢?
fixopen
2004-09-10
打赏
举报
回复
to zgy166(昆深)
对void型的指针进行操作之前都应该转型为你想要的类型。
不然是无法正确执行代码的。这是程序员的责任!
呵呵,开个玩笑,我如果要进行free呢?也要类型转换?
fixopen
2004-09-10
打赏
举报
回复
你觉得T'的dtor在vtbl中的偏移量一定跟T相同?
如果C中dtor在vtbl中的偏移量跟T'不同,确实会有问题,但就是说,如果C++编译器允许我做这样的转换,但不保证这样的转换是安全的?他会不会不修改offset?尤其是向void*转换时?那样的话,就会调用到正确的析构了。
zgy166
2004-09-10
打赏
举报
回复
对void型的指针进行操作之前都应该转型为你想要的类型。
不然是无法正确执行代码的。这是程序员的责任!
fixopen
2004-09-10
打赏
举报
回复
也可能sizeof(T') <> sizeof(T)呀。
所以sizeof(C) <> sizeof(T)应该没有关系
yndfcd
2004-09-10
打赏
举报
回复
不能delete一个void类型的指针.
fixopen
2004-09-10
打赏
举报
回复
T* o = new T'();
delete (T*)o; //T' dtor
如果这个不出问题的话,有理由认为
T* o = new T'();
delete (C*)o;
会出问题?
当然,我说的都是他们的dtor是虚的。
哦,我看出可能的问题是什么了,可能的问题是void*的delete会跟free一样,也就是没有析构的调用,因为它毕竟是一个原始类型。
加载更多回复(43)
C++中new与
delete
问题
学习
C++中new与
delete
问题
学习 一.new char与
delete
问题
1.
问题
程序 #include using namespace std; void main() { char* des = new char(); des = "testing!"; cout<
delete des; /
C++里 数组new 和
delete
问题
//C++里 数组new 和
delete
问题
//对于数组new的不同方式 和不同的释放方法 //---------------------------------------------------------------- // 创建字符指针数组 char **parr = new char*[100]; //注意这里是**parr // 释放各个字符数组 for (int i =0; i < 100; i++)
delete
[]
mysql
delete
问题
,mysql
delete
的
问题
小结 | 很文博客
关于mysql
delete
的
问题
,需要的朋友可以参考下。由于mysql数据库的相关内部
问题
导致
delete
from table where col not in (select col from table group by xx)会提示报错我们要做的是createtabletmpseletecolfromtablegroupbyxx;
delete
fromtablewh...
ClickHouse删除数据之
delete
问题
详解
深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!因此收集整理了一份《Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
C++基础系列:指针移动后
delete
问题
实现去掉字符串中空格的功能。 其间发现值得注意的几点: !!以下为错误代码!!class test4 { public: int main4() { const char *inbuf = " a string with space ! "; char *outbuf = new char[50]; if (inbuf
C++ 语言
65,187
社区成员
250,526
社区内容
发帖
与我相关
我的任务
C++ 语言
C++ 语言相关问题讨论,技术干货分享,前沿动态等
复制链接
扫一扫
分享
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++
技术论坛(原bbs)
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
请不要发布与C++技术无关的贴子
请不要发布与技术无关的招聘、广告的帖子
请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下
试试用AI创作助手写篇文章吧
+ 用AI写文章