vector中自定义字符串类的问题

fairchild811 2009-08-25 01:06:52
类定义:

class myStr{
char *t;
public:
myStr(char *s)
{
if(s != NULL)
{
t = new char[strlen(s) + 1];
strcpy(t, s);
}
}

friend ostream &operator << (ostream &os, myStr &ms)
{
return (os << ms.t);
}

~myStr()
{
cout << "deleting\n";
delete []t;
}
};

主函数:

vector<myStr> vms;
char str[100];
cin.getline(str, 100);
char *token = new char[20];
token = strtok(str, " ");
while(token != NULL)
{
vms.push_back(token);
token = strtok(NULL, " ");
}
cout << "the string you input is\n";
for(unsigned int ix = 0; ix < vms.size(); ix++)
cout << vms[ix] << " ";

问题是: 析构函数中的deleting紧跟在push_back语句后面就会输出,为什么在那个地方会执行析构函数,导致输出乱码?

winxp sp2 + cb2009, 包含了相应的头文件
...全文
350 27 打赏 收藏 转发到动态 举报
写回复
用AI写文章
27 条回复
切换为时间正序
请发表友善的回复…
发表回复
fairchild811 2009-09-01
  • 打赏
  • 举报
回复
晕死,该定义的我都定义了,只是帖子里没贴出来,输出结果是一样的:-)
Dave888Zhou 2009-08-31
  • 打赏
  • 举报
回复
作为一个好的设计习惯,有指针成员的类,其构造函数、拷贝构造函数、赋值运算符、析构函数都得自定义。特别对于单参数的构造函数,你还要考虑是否允许它进行隐式类型转换,如果不允许,就要将单参数的构造函数声明为explicit的。
fairchild811 2009-08-31
  • 打赏
  • 举报
回复
[Quote=引用 23 楼 taodm 的回复:]
楼主自定义的拷贝构造在哪里?
[/Quote]

自定义的拷贝构造我加入过,不过输出结果一样,所以帖子内就没有贴出来
bfzhao 2009-08-28
  • 打赏
  • 举报
回复
你的对象不符合标准库容器对其中保存序列的对象的要求,亦即,你的对象不是可赋值的和可拷贝构造的,除非你加入上述实现。
在调用push_back之前,编译器就会根据该函数的接口要求,自动构造临时对象,然后加入到vector。临时对象析构的时候,vector中的对象就不是正常状态了,所以输出乱码。楼上多的什么优化不能发生在调用函数之前。
taodm 2009-08-28
  • 打赏
  • 举报
回复
楼主自定义的拷贝构造在哪里?
fairchild811 2009-08-28
  • 打赏
  • 举报
回复
up 一下。。。
fairchild811 2009-08-27
  • 打赏
  • 举报
回复
cbuilder 2009

我用codeblocks 8.0.2, (g++ complier)

结果也是一样,输入一个单词,析构1次,2个析构3次,3个6次,4个7次。。。

应该就是push_back()内的问题,不过就算有临时变量析构了,vector内的变量也不应该析构啊,重载=我也试过了,一样的结果,这个vector的具体实现不知道是什么样的?
fairchild811 2009-08-26
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 gnuser 的回复:]
引用 15 楼 fairchild811 的回复:
引用 13 楼 pengzhixi 的回复:
你push对象进去的话肯定会有临时对象产生的


恩.谢谢.不过我自定义了类的拷贝构造函数和=重载函数(两个函数中都有输出以检查哪个函数被调用了)时.push_back时只有拷贝构造函数的输出.不过析构函数被调用的次数被构造函数要多


只有拷贝构造函数的输出,恰恰说明产生了临时对象啊。。。
[/Quote]

这个没有必然联系吧...
fairchild811 2009-08-26
  • 打赏
  • 举报
回复
我输入的句子是i hope so

构造函数调用了3次,析构函数为6次.
amossavez 2009-08-26
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 fairchild811 的回复:]
我输入的句子是i hope so

构造函数调用了3次,析构函数为6次.
[/Quote]
你用的什么编译器?
gnuser 2009-08-25
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 fairchild811 的回复:]
引用 13 楼 pengzhixi 的回复:
你push对象进去的话肯定会有临时对象产生的


恩.谢谢.不过我自定义了类的拷贝构造函数和=重载函数(两个函数中都有输出以检查哪个函数被调用了)时.push_back时只有拷贝构造函数的输出.不过析构函数被调用的次数被构造函数要多
[/Quote]

只有拷贝构造函数的输出,恰恰说明产生了临时对象啊。。。
pengzhixi 2009-08-25
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 fairchild811 的回复:]
引用 13 楼 pengzhixi 的回复:
你push对象进去的话肯定会有临时对象产生的


恩.谢谢.不过我自定义了类的拷贝构造函数和=重载函数(两个函数中都有输出以检查哪个函数被调用了)时.push_back时只有拷贝构造函数的输出.不过析构函数被调用的次数被构造函数要多
[/Quote]
有些是调用了拷贝构造函数啊. 你把拷贝构造函数调用的数量和构造函数的调用次数加起来看看
fairchild811 2009-08-25
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 pengzhixi 的回复:]
你push对象进去的话肯定会有临时对象产生的
[/Quote]

恩.谢谢.不过我自定义了类的拷贝构造函数和=重载函数(两个函数中都有输出以检查哪个函数被调用了)时.push_back时只有拷贝构造函数的输出.不过析构函数被调用的次数被构造函数要多
jhony_lee 2009-08-25
  • 打赏
  • 举报
回复
你把类的拷贝构造函数和=重载函数写上,不要用默认生成的
wanghao111 2009-08-25
  • 打赏
  • 举报
回复
学习 帮顶
pengzhixi 2009-08-25
  • 打赏
  • 举报
回复
你push对象进去的话肯定会有临时对象产生的
ysysbaobei 2009-08-25
  • 打赏
  • 举报
回复
顶下
fairchild811 2009-08-25
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 jn989 的回复:]
vms.push_back(token);
我的理解是:token是个字符串,而vms是myStr的向量,不能直接加入;所以由token生成临时对象,然后将临时对象拷贝到vms,最后被拷贝的那个临时对象被析构,故调用析构函数
[/Quote]

谢谢,4楼应该和3楼是差不多一个意思.先构造一个对象,再push_back我也试过了,结果一样
wesleyluo 2009-08-25
  • 打赏
  • 举报
回复
学习了。
fairchild811 2009-08-25
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 fox000002 的回复:]
lz 可以调试一下,跟踪 vector 中 push_back 的源代码

对于 vector <myStr> vms,

执行 push_back 会产生临时的 myStr 对象,再赋值给 vector 中的元素

因为考虑深拷贝的问题, myStr 不能用 = 直接赋值,必须重载 operator =

没有重载 operator=,就出现了非法指针,乱码了
[/Quote]

谢谢.我也这样想过.我试过重载 operator =
不过push_back时,并不执行operator=,而是执行myStr(char *s)这个函数.

即使push_back中使用了对象的赋值,现在的编译器也会优化为直接构造,而不会产生临时对象
加载更多回复(7)

64,281

社区成员

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

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