从复制构造函数调用构造函数时,它也会调用析构函数
while calling a constructor from copy constructor it calls destructor too
我编写了一个程序,使用复制构造函数来复制对象。在复制构造函数中,我调用了构造函数来创建内存并复制内容。它在构造函数中成功完成,但在构造函数结束后立即调用析构函数,我得到了垃圾值。最后在主函数中,如果我试图破坏新创建的对象,程序就会崩溃。为什么会这样?
这是代码。
#include<iostream>
using namespace std;
class Test
{
public:
int a;
int *p;
Test(int a,int b,int c)
{
this->a=a;
p=new int[2];
p[0]=b;
p[1]=c;
cout<<"\n\n "<<this->a<<" "<<this->p[0]<<" "<<this->p[1];
}
Test(const Test &ob)
{
Test(ob.a,ob.p[0],ob.p[1]);
cout<<"\n\n "<<this->a<<" "<<this->p[0]<<" "<<this->p[1];
}
void print()
{
cout<<"\n\n\n "<<a<<" "<<p[0]<<" "<<p[1];
}
~Test()
{
cout<<"\n\n\n DESTRUCTOR CALLED "<<endl;
delete [] p;
}
};
int main()
{
Test *ob1=new Test(2,3,4);
cout<<"\n\n\n ob2: new object";
Test *ob2=new Test(*ob1);
cout<<"\n\n\n ob1";
(*ob1).print();
cout<<"\n\n\n ob2";
(*ob2).print();
delete ob1;
delete ob2;
return 1;
}
产生输出:
2 3 4
ob2: 新对象
2 3 4
调用了析构函数
9968956 9968956 0
ob1
2 3 4
ob2
9968956 9968956 0
调用了析构函数
调用了析构函数
"then the program stops working i.e. crashes".....
我明白在这种情况下会发生什么,但请解释一下为什么在删除对象 ob2 时程序会在这种情况下崩溃。
谢谢
复制构造函数确实什么都不做。 Test(ob.a,ob.p[0],ob.p[1]);
只是创建一个临时的 Test
,它将立即被销毁。 Test
的所有成员根本没有初始化。
你想要 delegate constructor,这是 C++11 的特性。
Test(const Test &ob) : Test(ob.a, ob.p[0], ob.p[1])
{
cout<<"\n\n "<<this->a<<" "<<this->p[0]<<" "<<this->p[1];
}
这里至少有几个问题。
首先,int* p
是指向单个整数的指针,但您将其视为指向整数数组的指针。 p[1]
不一定是您拥有的内存。
关于您意外的析构函数调用,您的复制构造函数会创建一个临时 Test
对象,当您退出复制构造函数的范围时,该对象会被销毁。这就是为什么您在尝试从复制构造创建新对象后立即看到析构函数被调用的原因。请看@songyuanyao关于使用委托构造函数的回答
此外,您对 delete
的调用没有任何效果,因为它们是在您对 return
的调用之后进行的。
最后,作为文体说明,return 0;
通常表示您的程序正常结束。 return <some_nonzero_number>;
通常用于向调用者表明您的程序由于某些错误而结束。
编辑:p=new int(2*sizeof(int));
仍然不是您想使用 p
的目的,因为您正在尝试使用它。这只是创建一个指向单个整数的指针,其中整数的值为 2 * 4 = 8。
要正确使用 p
,您的意思可能是 p = new int[2];
在这种情况下,请记住在析构函数中使用 delete [] p;
。
我编写了一个程序,使用复制构造函数来复制对象。在复制构造函数中,我调用了构造函数来创建内存并复制内容。它在构造函数中成功完成,但在构造函数结束后立即调用析构函数,我得到了垃圾值。最后在主函数中,如果我试图破坏新创建的对象,程序就会崩溃。为什么会这样?
这是代码。
#include<iostream>
using namespace std;
class Test
{
public:
int a;
int *p;
Test(int a,int b,int c)
{
this->a=a;
p=new int[2];
p[0]=b;
p[1]=c;
cout<<"\n\n "<<this->a<<" "<<this->p[0]<<" "<<this->p[1];
}
Test(const Test &ob)
{
Test(ob.a,ob.p[0],ob.p[1]);
cout<<"\n\n "<<this->a<<" "<<this->p[0]<<" "<<this->p[1];
}
void print()
{
cout<<"\n\n\n "<<a<<" "<<p[0]<<" "<<p[1];
}
~Test()
{
cout<<"\n\n\n DESTRUCTOR CALLED "<<endl;
delete [] p;
}
};
int main()
{
Test *ob1=new Test(2,3,4);
cout<<"\n\n\n ob2: new object";
Test *ob2=new Test(*ob1);
cout<<"\n\n\n ob1";
(*ob1).print();
cout<<"\n\n\n ob2";
(*ob2).print();
delete ob1;
delete ob2;
return 1;
}
产生输出:
2 3 4
ob2: 新对象 2 3 4
调用了析构函数
9968956 9968956 0
ob1
2 3 4
ob2
9968956 9968956 0
调用了析构函数
调用了析构函数
"then the program stops working i.e. crashes".....
我明白在这种情况下会发生什么,但请解释一下为什么在删除对象 ob2 时程序会在这种情况下崩溃。 谢谢
复制构造函数确实什么都不做。 Test(ob.a,ob.p[0],ob.p[1]);
只是创建一个临时的 Test
,它将立即被销毁。 Test
的所有成员根本没有初始化。
你想要 delegate constructor,这是 C++11 的特性。
Test(const Test &ob) : Test(ob.a, ob.p[0], ob.p[1])
{
cout<<"\n\n "<<this->a<<" "<<this->p[0]<<" "<<this->p[1];
}
这里至少有几个问题。
首先,int* p
是指向单个整数的指针,但您将其视为指向整数数组的指针。 p[1]
不一定是您拥有的内存。
关于您意外的析构函数调用,您的复制构造函数会创建一个临时 Test
对象,当您退出复制构造函数的范围时,该对象会被销毁。这就是为什么您在尝试从复制构造创建新对象后立即看到析构函数被调用的原因。请看@songyuanyao关于使用委托构造函数的回答
此外,您对 delete
的调用没有任何效果,因为它们是在您对 return
的调用之后进行的。
最后,作为文体说明,return 0;
通常表示您的程序正常结束。 return <some_nonzero_number>;
通常用于向调用者表明您的程序由于某些错误而结束。
编辑:p=new int(2*sizeof(int));
仍然不是您想使用 p
的目的,因为您正在尝试使用它。这只是创建一个指向单个整数的指针,其中整数的值为 2 * 4 = 8。
要正确使用 p
,您的意思可能是 p = new int[2];
在这种情况下,请记住在析构函数中使用 delete [] p;
。