有关动态对象数组的问题:

FrankQf 2002-07-03 11:06:21
请看代码:
#include <stdio.h>
#include <iostream.h>
#include <string.h>
#include <malloc.h>

class a
{
public :
a(int c1,int d1,char *p)
{
c=c1;
d=d1;
strcpy(string,p);
}
~a()
{
cout<<"destructor called for:"<<string<<endl;
}

int sum();
int e;
private:
int c,d;
char string[50]; //Record the object name.
};

int a::sum(void)
{
return (c+d+e);
}

void main(void)
{
char str[50];
a *objArr;

objArr=(a *)malloc(sizeof(a)*10);
int i=0,j=0;
for (i=0;i<10;i++,j++)
{
sprintf(str,"objArr[%d]",i);
*(objArr+i) = a(i,j,str);
(*(objArr+i)).e = 0;
}
for (i=0;i<10;i++)
{
printf("(*(objArr+%d)).sum()=%d\n",i,(*(objArr+i)).sum());
}
free(objArr);
}

输出结果如下:
destructor called for:objArr[0]
destructor called for:objArr[1]
destructor called for:objArr[2]
destructor called for:objArr[3]
destructor called for:objArr[4]
destructor called for:objArr[5]
destructor called for:objArr[6]
destructor called for:objArr[7]
destructor called for:objArr[8]
destructor called for:objArr[9]
(*(objArr+0)).sum()=0
(*(objArr+1)).sum()=2
(*(objArr+2)).sum()=4
(*(objArr+3)).sum()=6
(*(objArr+4)).sum()=8
(*(objArr+5)).sum()=10
(*(objArr+6)).sum()=12
(*(objArr+7)).sum()=14
(*(objArr+8)).sum()=16
(*(objArr+9)).sum()=18
Press any key to continue

问:
为什么动态分配的objArr对象在初始化时就被析构掉了?并且在对象释放掉後还依然能访问其数据成员,例如上面的sum函数?
...全文
103 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
FrankQf 2002-07-04
  • 打赏
  • 举报
回复
还有,请问mylove0618(ADT):const char * b()const {return string;}这里使用常成员函数,有什么特别的意义吗?谢谢!
FrankQf 2002-07-04
  • 打赏
  • 举报
回复
请问mylove0618(ADT):“产生临时对象以及使用默认赋值运算符,会给程序设计带来很多隐患”,在我的这段代码中体现在哪些方面?真诚感谢!
另外:在你所修改的代码中,提前释放了string,在后来的对象成员函数中引用到了,将其打印出来,这儿好像有问题。是不是应该在最后释放?
RedFire 2002-07-03
  • 打赏
  • 举报
回复
你看这一句中的a(i, j, str);是你产生的一个临时变量。
*(objArr+i) = a(i,j,str);

所以说你看到的析构函数的输出,是这个临时变量的,并不是你的objArr对象的。

还有一个问题是并于C++中为什么分引入new和delete运算符的。new与malloc的不同之处在于它会调用类的构造函数;delete和free的不同是它会调用类的析构函数。所以实际上,你的程序中,objArr的构造和析构函数都没有被调用。
zhang1000 2002-07-03
  • 打赏
  • 举报
回复
objArr=(a *)malloc(sizeof(a)*10);只是分配内存空间,并没有构造对象
真正的构造出现在
for (i=0;i<10;i++,j++)
{
sprintf(str,"objArr[%d]",i);
*(objArr+i) = a(i,j,str);
(*(objArr+i)).e = 0;
}
中,而这是一个复合语句,跳出后就析构对象.
至于析构后还能访问,则是因为内存中有这么个信息,
让你这样(*(objArr+9))一下就成了对象(即完成了类型转化)
zhang1000 2002-07-03
  • 打赏
  • 举报
回复
To alula(alula):
"没有默认构建函数",如果你没有提供,编译器会给你一个,所以好象不会有这个情况.
你的意思是,不提供构造函数的情况下又要求对象有缺省值.
你可以参考一下"静态成员"的论述,
可以把要有缺省的成员定义为static,
如:
class testa
{
public:
static int a;
};

int testa::a=12;

main()
{
testa *pa;
pa=new testa[100];
.....
if(pa) delete [] pa;
}

不过最好不要这样,因为定义为static后只能由static成员函数操作.
mylove0618 2002-07-03
  • 打赏
  • 举报
回复
产生临时对象以及使用默认赋值运算符,会给程序设计带来很多隐患。应该尽量避免。另外,最好使用new,delete操作符。可以安全调用构造函数和析构函数。
下面的例子就说明了你的方法的问题,可以看一下:
#include <stdio.h>
#include <iostream.h>
#include <string.h>
#include <malloc.h>

class a
{
public :
a(int c1,int d1,char *p)
{
c=c1;
d=d1;
string=(char *)malloc(sizeof(char)*50);
strcpy(string,p);
}
~a()
{
cout<<"destructor called for:"<<string<<endl;
free(string);

}
const char * b()const {return string;}
int sum();
int e;
private:
int c,d;
char* string; //Record the object name.
};

int a::sum(void)
{
return (c+d+e);
}

void main(void)
{
char str[50];
a *objArr;

objArr=(a *)malloc(sizeof(a)*10);

int i=0,j=0;
for (i=0;i<10;i++,j++)
{
sprintf(str,"objArr[%d]",i);
*(objArr+i)=a(i,j,str);
(*(objArr+i)).e = 0;
}
for (i=0;i<10;i++)
{
printf("(*(objArr+%d)).sum()=%d\n",i,(*(objArr+i)).sum());
printf("%s\n",objArr[i].b());
}

free(objArr);
}
alula 2002-07-03
  • 打赏
  • 举报
回复
借问一下, 实现下面这句的效果的做法?
//a* pa = new a(1, 2, "asdf")[100]; // 当然这句是错的。

就是没有默认构建函数的时候,如何申请多个对象de空间?

69,336

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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