为什么构造函数和析构函数调用次数不同,分别是哪个对象调用了构造函数和析构函数
展开全部
这个问题其实隐含了2个技术问题。 你如果能在class的定义中中添加“拷贝构造”函数如下:
class xiexin
{
public:
...
xiexin(const xiexin&) {cout << "copy contructor" << endl;}
...
}
情况就比较清楚;
① 构造函数+拷贝构造的调用次数=析构函数的调用次数。
因为你的友元display()和静态成员calculate()的传人参数都是按值传递的,结果就要先构造一个类的临时对象, 然后调用拷贝构造来给它赋值。
② 但似乎临时对象的缺省构造函数没有被调用。 这就和具体的编译器技术有关了。现代的编译器都比较智能,为了提高效率,都能省略构造函数的调用(因为有的类会比较大, 构造函数又可能慢,反正还要拷贝的, 所以一般都分配一块内存,有可能零填充一下,然后后面再调用拷贝构造来初始化, 相当于2合1的简化),因此你只能看到拷贝构造被调用,而构造没有被调用的情况。
③ 你要是把display和calculate的参数都修改为引用,即
static int calculate(xiexin& obj);
friend void display(xiexin& obj);
再输出看看? 一共只有2次构造和2次析构, 成对出现了~~
又: 为了醒目, 你的两个构造函数,在输出前可以分别添加"Constructor 1 "和"Constructor 2 "以方便记数(注意1和2后面要有一个空格)。
class xiexin
{
public:
...
xiexin(const xiexin&) {cout << "copy contructor" << endl;}
...
}
情况就比较清楚;
① 构造函数+拷贝构造的调用次数=析构函数的调用次数。
因为你的友元display()和静态成员calculate()的传人参数都是按值传递的,结果就要先构造一个类的临时对象, 然后调用拷贝构造来给它赋值。
② 但似乎临时对象的缺省构造函数没有被调用。 这就和具体的编译器技术有关了。现代的编译器都比较智能,为了提高效率,都能省略构造函数的调用(因为有的类会比较大, 构造函数又可能慢,反正还要拷贝的, 所以一般都分配一块内存,有可能零填充一下,然后后面再调用拷贝构造来初始化, 相当于2合1的简化),因此你只能看到拷贝构造被调用,而构造没有被调用的情况。
③ 你要是把display和calculate的参数都修改为引用,即
static int calculate(xiexin& obj);
friend void display(xiexin& obj);
再输出看看? 一共只有2次构造和2次析构, 成对出现了~~
又: 为了醒目, 你的两个构造函数,在输出前可以分别添加"Constructor 1 "和"Constructor 2 "以方便记数(注意1和2后面要有一个空格)。
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询