c++析构函数调用问题:为啥调用了四次,而构造函数只调用了2次?

#include<iostream>classcircle{public:circle(inta,intb){r=a;p=b;std::cout<<"构造函数调用完毕"<... #include<iostream>
class circle
{
public:
circle(int a,int b)
{
r=a;
p=b;
std::cout<<"构造函数调用完毕"<<std::endl;
}
~circle(){std::cout<<"析构函数调用完毕"<<std::endl;}
int getr()
{
return r;
}
int getp()
{
return p;
}
private:
int r;
int p;
};
double face(circle a)
{
double b;
b=3.14159*(a.getr())*(a.getr());
return b;
}
void main()
{
circle cobj(3,4);
std::cout<<cobj.getp()<<std::endl;
std::cout<<cobj.getr()<<std::endl;
std::cout<<face(cobj)<<std::endl;;
circle cobq(5,6);
std::cout<<face(cobq)<<std::endl;;
}
#include<iostream>
class circle
{
public:
circle(int a,int b)
{
r=a;
p=b;
std::cout<<"构造函数调用完毕"<<std::endl;
}
~circle(){std::cout<<"析构函数调用完毕"<<std::endl;}
int getr()
{
return r;
}
int getp()
{
return p;
}
private:
int r;
int p;
};
double face(circle &a)
{
double b;
b=3.14159*(a.getr())*(a.getr());
return b;
}
void main()
{
circle cobj(3,4);
std::cout<<cobj.getp()<<std::endl;
std::cout<<cobj.getr()<<std::endl;
std::cout<<face(cobj)<<std::endl;;
circle cobq(5,6);
std::cout<<face(cobq)<<std::endl;;
}
而这样又是调用了2次?
展开
 我来答
xoaxa
2014-07-22 · TA获得超过8607个赞
知道大有可为答主
回答量:6415
采纳率:72%
帮助的人:3400万
展开全部
构造函数是由语句circle cobj(3,4);和circle cobq(5,6);调用的,另外两次是由复制构造函数生成临时类对象,发生在函数face()的参数传递的时候,由于你没有提供复制构造函数,系统会自动生成,所以程序结束前,需要4次调用析构函数。
对的,当使用引用传递时,无需用复制构造函数生成新的对象,那么析构函数只需2次就可以了。
追问
那么复制构造函数生成昨时类对象的话,face的参数是一个对象而不是参数,构造函数在没有参数的情况下如何构造呢?是不是说cobj在析构函数调用前一直存在于栈中,只到程序结束,所以,往face里传对象时,复制构造函数时能自动调用这个对象的r 和p?
追答
上面已经回答了,你第一次上传的代码中,函数face()的参数是按值传递的,所以需要复制构造函数,而第二次上传的代码是按引用传递的,此时不会调用复制构造函数,故只需两次调用析构函数。
每个类都有默认复制构造函数,如果不显式给出,需要时,就会调用默认复制构造函数,显式给出时,默认复制构造函数被隐藏。
ckpyn
2014-07-22 · TA获得超过2052个赞
知道小有建树答主
回答量:1179
采纳率:85%
帮助的人:362万
展开全部
构造函数不是程序员调用,而是C++定义或生成对象时,由系统自动调用的。
在这里虽然调用了4次成员函数,但它们都没有生成对象,所以,不引发构造函数的调用。
代码中,定义了2个对象,所以,定义的这2个对象引发了2次构造函数的调用
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
小兆86
2014-07-22 · TA获得超过802个赞
知道小有建树答主
回答量:990
采纳率:25%
帮助的人:860万
展开全部
你是指face函数调用里面的那个形参吗?
这个问题讲起来很复杂,但是简单讲就是,对于面向对象的C++编译器,将会优化所有的函数形参,避免直接使用传值调用。
即便在代码中和c语言中一模一样是个传值调用,不是指针也不是引用,但是编译器本身将自动将传值进行优化,最起码的变成实参的一个引用。
在你的例子里面因为face函数并没用对a对象的成员进行修改,所以a就会变成实参的引用,这时候并没有申请一个新的类实例,也就不会执行构造函数了。
追问
为啥是在输出面积前调用析构函数,已析构弹出栈了怎么还能输出结果?
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 更多回答(1)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式