有关异常和构造函数的问题.cpp

时间:2021-06-20 19:30:04
# include <iostream>
using namespace std;

class A
{
public:
A(int i1, int i2):a(i1), b(i2)
{
cout << "构造函数被调用" << endl;
}

~A()
{
cout << "析构函数被调用" << endl;
}

int a;
int b;
};

void f(void)
{
A aa(6,6);
throw aa;
}

int main(void)
{
cout << "YYY" << endl;
try
{
f();
}
catch (A a)
{
cout << a.a << " " << a.b << endl;
}
cout << "XXX" << endl;

return 0;
}
/*
在Vc++6.0中的输出结果是
----------------
YYY
构造函数被调用
析构函数被调用
6 6
析构函数被调用
析构函数被调用
XXX
Press any key to continue
----------------
我的问题是为什么会有三个析构函数,只有一个构造函数? 请诸位高手指点

*/

6 个解决方案

#1


#   include   <iostream> 
using   namespace   std; 

class   A 

public: 
A(int   i1,   int   i2):a(i1),   b(i2) 

cout   < <   "构造函数被调用"   < <   endl; 


~A() 

cout   < <   "析构函数被调用"   < <   endl; 


int   a; 
int   b; 
}; 

void   f(void) 

A   aa(6,6); //第一次构造
throw   aa; //再次调用A(const A& a)构造?


int   main(void) 

cout   < <   "YYY"   < <   endl; 
try 

f(); 

catch   (A   a) //这里调用A(const A& a)再次构造,你的那个构造不会被调用

cout   < <   a.a   < <   "   "   < <   a.b   < <   endl; 

cout   < <   "XXX"   < <   endl; 

return   0; 

#2


因为你的程序*构造了三个实例:
A aa(6,6); // 调用程序中定义的构造函数A::A(int i1, int i2) : a(i1), b(i2)。
throw aa; // 调用引用构造函数A::A(A &ref),这个是自动生成的。
catch (A a) // 调用引用构造函数A::A(A &ref)。
所以要析构三次。你可以添加一个构造函数:
A::A(A &ref)
{
this->a = ref.a;
this->b = ref.b;
cout << "构造函数被调用" << endl;
}

这样就可以看到三次构造了。

#3


to cnzdgs:
throw aa; // 调用引用构造函数A::A(A &ref),这个是自动生成的。
请问这里为什么要调用拷贝构造函数???aa不是已经生成了吗?还要再生成一次?
谢谢!

#4


throw  的时候相当于传值出去了。

#5


在throw aa的过程中,对aa存在一次拷贝,而原始的aa随着堆栈的回缩而消失。所以会出现一次复制构造函数。同样也存在一次对原始aa的析构。
之后,通过catch接收对象,因为你采用了用对象来接收的方式(应该采用引用接收),所以又出现了一次复制构造函数的调用,这样又产生了一个新的aa对象。在catch从句完成后,这个新的aa消失了。同时,你的第一次拷贝对象也消失了。
因此这里出现了三次析构。

#6


我试了一下,程序如下:
# include <iostream>
using namespace std;

class A
{
public:
A(int i1, int i2):a(i1), b(i2)
{
cout << "构造函数被调用" << endl;
}

~A()
{
cout << "析构函数被调用" << endl;
}

A(A &ref)
{
this->a = ref.a;
this->b = ref.b;
cout << "构造函数被调用 哈哈" << endl;
}

int a;
int b;
};

void f(void)
{
A aa(6,6);
throw aa; //1此析构
}

int main(void)
{
cout << "YYY" << endl;
try
{
f();
}
catch (A a)
{
cout << a.a << " " << a.b << endl;
}
cout << "XXX" << endl;

return 0;
}
/*
在Vc++6.0中的输出结果是
----------------
YYY
构造函数被调用
构造函数被调用 哈哈
构造函数被调用 哈哈
析构函数被调用
6 6
析构函数被调用
析构函数被调用
XXX
Press any key to continue
---------------------
*/
谢谢大家

#1


#   include   <iostream> 
using   namespace   std; 

class   A 

public: 
A(int   i1,   int   i2):a(i1),   b(i2) 

cout   < <   "构造函数被调用"   < <   endl; 


~A() 

cout   < <   "析构函数被调用"   < <   endl; 


int   a; 
int   b; 
}; 

void   f(void) 

A   aa(6,6); //第一次构造
throw   aa; //再次调用A(const A& a)构造?


int   main(void) 

cout   < <   "YYY"   < <   endl; 
try 

f(); 

catch   (A   a) //这里调用A(const A& a)再次构造,你的那个构造不会被调用

cout   < <   a.a   < <   "   "   < <   a.b   < <   endl; 

cout   < <   "XXX"   < <   endl; 

return   0; 

#2


因为你的程序*构造了三个实例:
A aa(6,6); // 调用程序中定义的构造函数A::A(int i1, int i2) : a(i1), b(i2)。
throw aa; // 调用引用构造函数A::A(A &ref),这个是自动生成的。
catch (A a) // 调用引用构造函数A::A(A &ref)。
所以要析构三次。你可以添加一个构造函数:
A::A(A &ref)
{
this->a = ref.a;
this->b = ref.b;
cout << "构造函数被调用" << endl;
}

这样就可以看到三次构造了。

#3


to cnzdgs:
throw aa; // 调用引用构造函数A::A(A &ref),这个是自动生成的。
请问这里为什么要调用拷贝构造函数???aa不是已经生成了吗?还要再生成一次?
谢谢!

#4


throw  的时候相当于传值出去了。

#5


在throw aa的过程中,对aa存在一次拷贝,而原始的aa随着堆栈的回缩而消失。所以会出现一次复制构造函数。同样也存在一次对原始aa的析构。
之后,通过catch接收对象,因为你采用了用对象来接收的方式(应该采用引用接收),所以又出现了一次复制构造函数的调用,这样又产生了一个新的aa对象。在catch从句完成后,这个新的aa消失了。同时,你的第一次拷贝对象也消失了。
因此这里出现了三次析构。

#6


我试了一下,程序如下:
# include <iostream>
using namespace std;

class A
{
public:
A(int i1, int i2):a(i1), b(i2)
{
cout << "构造函数被调用" << endl;
}

~A()
{
cout << "析构函数被调用" << endl;
}

A(A &ref)
{
this->a = ref.a;
this->b = ref.b;
cout << "构造函数被调用 哈哈" << endl;
}

int a;
int b;
};

void f(void)
{
A aa(6,6);
throw aa; //1此析构
}

int main(void)
{
cout << "YYY" << endl;
try
{
f();
}
catch (A a)
{
cout << a.a << " " << a.b << endl;
}
cout << "XXX" << endl;

return 0;
}
/*
在Vc++6.0中的输出结果是
----------------
YYY
构造函数被调用
构造函数被调用 哈哈
构造函数被调用 哈哈
析构函数被调用
6 6
析构函数被调用
析构函数被调用
XXX
Press any key to continue
---------------------
*/
谢谢大家