auto_ptr问题

OOPhaisky 2006-08-27 05:47:57
---------------------------------------------------
head.h:
#include <memory>

class X{
public:
class Y{};
std::auto_ptr<Y> py;
};
---------------------------------------------------
a.cpp:
#include "head.h"

int main(int argc, char *argv[]){
X x;
return 0;
}
---------------------------------------------------
b.cpp(此时就相当为空,仅仅#include一个头文件而已):
#include "head.h"
---------------------------------------------------
此时编译成功。

现在作修改,将head.h中class Y的定义转移到b.cpp中:
---------------------------------------------------
head.h:
#include <memory>

class X{
public:
class Y;
std::auto_ptr<Y> py;
};
---------------------------------------------------
a.cpp:
#include "head.h"

int main(int argc, char *argv[]){
X x;
return 0;
}
---------------------------------------------------
b.cpp(此时就相当为空,仅仅#include一个头文件而已):
#include "head.h"

class X::Y{
};
---------------------------------------------------
此时编译就有问题了:在vs中是一个警告,而在g++中则是error。
大家不要错误地认为是由于“std::auto_ptr<Y> py;需要class Y的定义”而导致的错误(可能在vc6中是这么要求的,但是标准并没有这方面的强制要求)。这其实是more exceptional c++ 条款30,185页的一个问题,结合书上的解释,我的理解是:因为在a.cpp的main函数中有“X x;”,所以在main函数的结尾编译器会自动安插一个“x.~x();”(即调用x对象的析构函数),而编译器为class X自动合成的析构函数中肯定会有类似“py.~auto_ptr<Y>();”之类的语句来调用数据成员的析构函数,并且由于编译器为class X自动合成的析构函数很小,所以编译器会将它设置为inline,这样一来“py.~auto_ptr<Y>();”就出现在main函数中了,这也就要求在a.cpp中将会有auto_ptr<Y>::~auto_ptr<Y>的实例化点,而在auto_ptr<Y>::~auto_ptr<Y>的实例化点肯定需要用到class Y的定义,但是在a.cpp中没有class Y的定义,所以出现错误。

more exceptional c++中提供的解决方案(当然不是“在头文件中提供class Y的定义”了)是(185页):如果你不想提供Y的定义,就必须显式地写出X的析构函数,即使函数体为空。

但是这个方法并不好用,即使显式提供X的析构函数,编译仍然有问题(你可以试一试)。后来我想了一下,就算我们显式提供了X的析构函数,编译器仍然会在析构函数体中安插“调用数据成员析构函数”的代码,即X的析构函数中仍然会存在类似“py.~auto_ptr<Y>();”之类的语句,所以问题依然存在。

不知道我分析得对不对,望高手指教。
...全文
708 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
ModoRang 2006-09-21
  • 打赏
  • 举报
回复
友情帮顶。
OOPhaisky 2006-09-21
  • 打赏
  • 举报
回复
结贴了,时间好久了:)
OOPhaisky 2006-09-08
  • 打赏
  • 举报
回复
to sinall(人TMD就是动物):

但是Sutter的观点好像与我不同,他认为:只要给析构函数提供一个显式的定义就可以了......
我百思而不得其解,不知道是不是有其他什么微妙的原因。
sinall 2006-09-08
  • 打赏
  • 举报
回复
#include <boost/shared_ptr.hpp>

class X{
public:
~X() { }
class Y;
boost::shared_ptr<Y> py;
};
我试了下boost::shared_ptr,没有报warning。
你可以看看boost::shared_ptr的相关实现。
sinall 2006-09-08
  • 打赏
  • 举报
回复
楼主说得基本对:
Compiler Warning (level 2) C4150
deletion of pointer to incomplete type 'type'; no destructor called

The delete operator was called to delete the given type, which was declared but not defined. The compiler was unable to find any destructors for the given type.

Make sure that the class, structure, or union is defined before using the delete operator.

The following example generates this warning:

class IncClass;
void NoDestruct( IncClass* pIncClass )
{ delete pIncClass; }
—————————————————————————————————————————
就是说,要用delete的话,就要确保class、structure、union要定义!
OOPhaisky 2006-09-08
  • 打赏
  • 举报
回复
楼上的程序是怎么回事儿?
djfu 2006-09-07
  • 打赏
  • 举报
回复
#include <memory>
#include <iostream>
using namespace std;

class C
{
public:
C()
{
}
C(const char *p)
{
m_szBuf = new char[strlen(p) + 1];
strcpy(m_szBuf, p);
}
~C()
{
delete []m_szBuf;
}
char *GetBuf()
{
return m_szBuf;
}

private :
char *m_szBuf;

};

int main
{
char *pBuf = NULL;
{
auto_ptr<C> tc(new C("hello"));
cout << "This buf = " << tc->GetBuf() << endl;
pBuf = tc->GetBuf();
}

cout << "Now buf = " << pBuf << endl;

getchar();
return 0;
}
DLNU_LEI 2006-09-04
  • 打赏
  • 举报
回复
来学习的,顶一下!
junku_kong 2006-09-04
  • 打赏
  • 举报
回复
Study
universee 2006-09-01
  • 打赏
  • 举报
回复
mk
lyskyly 2006-08-31
  • 打赏
  • 举报
回复
顶一下
OOPhaisky 2006-08-31
  • 打赏
  • 举报
回复
自己再顶一下
OOPhaisky 2006-08-29
  • 打赏
  • 举报
回复
to UPCC(杂食动物):

按照你的意思,“std::auto_ptr<Y> py ”一定需要class Y的定义。
但是more exceptional c++却说,“如果你不想提供Y的定义,就必须显式地写出X的析构函数,即使函数体为空”,也就是说可以不提供Y的定义(虽然sutter的这个方法我表示怀疑,如题所说)。
Th_Pk_Ying 2006-08-29
  • 打赏
  • 举报
回复
原因是由于编译器把析构函数设置为内联引起的。
按书上的建议,可以把析构函数定义为非inline的,应该可以解决。

我试了一下,如果把析构函数的定义放在a.ccp中好像不行,如果放在b.cpp中就没有警告了,
我用的是vc7.0。lz可以试下,具体原因还在研究中。
Dong 2006-08-28
  • 打赏
  • 举报
回复
:)

std::auto_ptr<Y> py = std::auto_ptr<Y>(new Y);
kangji 2006-08-28
  • 打赏
  • 举报
回复
说真的,不明白楼主到底想说什么?
OOPhaisky 2006-08-28
  • 打赏
  • 举报
回复
jixingzhong(瞌睡虫:选择了远方,只顾风雨兼程!) ,对我的问题给点意见阿,到底怎么回事儿?你是怎么理解的?
jixingzhong 2006-08-28
  • 打赏
  • 举报
回复
^_^
jixingzhong 2006-08-28
  • 打赏
  • 举报
回复
呵呵, 没想到是 OOPhaisky (渴望成功) ...

先说了, 别忽悠我啊 ...
Roxxette 2006-08-28
  • 打赏
  • 举报
回复
学习学习
加载更多回复(1)

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧